Re: core.exception.InvalidMemoryOperationError@(0)
On Sunday, 25 January 2015 at 08:39:42 UTC, Bayan Rafeh wrote: On Sunday, 25 January 2015 at 00:43:43 UTC, Vladimir Panteleev wrote: On Saturday, 24 January 2015 at 12:16:38 UTC, Bayan Rafeh wrote: This problem is a tough one. I've been getting this error when I run my unittests, and apparently it is caused by attempting an allocation in the destructor from what little I could find online about the subject. The error is triggered once all my tests are complete, so I'm assuming the garbage collector is running before termination, but I tried placing logging messages in all my destructors and I didn't get anything, so none of them are being called. Is there any other possible reason to get this error? Hi, I created a wiki page which I hope will help you solve this problem: http://wiki.dlang.org/InvalidMemoryOperationError Hope this helps. Thank you very much, this will certainly be useful in debugging it. The allocations may be indirect. For example, formatting a string to log a message may allocate. Try marking your destructors as @nogc to see whether the compiler agrees. I tried what you said and I think I see the problem. I managed to create an example program that duplicates the problem: import std.stdio; class A { string path; this(string p) { path = p; } ~this() { } void a(){} void b(){} } class B { A a; this() { this.a = new A(laladiv); } ~this() { delete a; } } void main() { B a = new B(); B b = new B(); delete b; } The solution was just to remove the delete a from the destructor if someone comes across this later. Could someone tell me why though?
Re: core.exception.InvalidMemoryOperationError@(0)
On Sunday, 25 January 2015 at 08:41:25 UTC, Bayan Rafeh wrote: The solution was just to remove the delete a from the destructor if someone comes across this later. Could someone tell me why though? The non-reentrant bit applies to all GC operations, really - not just allocations. Explicit deletions are forbidden as well. Use of the delete keyword is discouraged, and in that context, it is also not used in a safe way. By the time B's destructor is called, the A instance might have been already collected by the garbage collector, causing a double free bug (one of the reasons to not use delete).
Re: crash on args.getopt
On Sunday, 25 January 2015 at 10:21:34 UTC, Suliman wrote: But is it good practice to fail with exception during passing unknown parameters? Maybe std.getopt.config.passThrough should be as default? I really can't remember Apps that crush if pass to in unknown parameters. Almost all programs fail with an error message, if you pass unknown parameter. Just catch that exception.
Re: using the full range of ubyte with iota
Vlad Levenfeld: What's this about !`[]` and std.range.uniform?? It's not in the documentation. It's an enhancement I have proposed. Bye, bearophile
Re: core.exception.InvalidMemoryOperationError@(0)
On Sunday, 25 January 2015 at 00:43:43 UTC, Vladimir Panteleev wrote: On Saturday, 24 January 2015 at 12:16:38 UTC, Bayan Rafeh wrote: This problem is a tough one. I've been getting this error when I run my unittests, and apparently it is caused by attempting an allocation in the destructor from what little I could find online about the subject. The error is triggered once all my tests are complete, so I'm assuming the garbage collector is running before termination, but I tried placing logging messages in all my destructors and I didn't get anything, so none of them are being called. Is there any other possible reason to get this error? Hi, I created a wiki page which I hope will help you solve this problem: http://wiki.dlang.org/InvalidMemoryOperationError Hope this helps. Thank you very much, this will certainly be useful in debugging it. The allocations may be indirect. For example, formatting a string to log a message may allocate. Try marking your destructors as @nogc to see whether the compiler agrees. I tried what you said and I think I see the problem. I managed to create an example program that duplicates the problem: import std.stdio; class A { string path; this(string p) { path = p; } ~this() { } void a(){} void b(){} } class B { A a; this() { this.a = new A(laladiv); } ~this() { delete a; } } void main() { B a = new B(); B b = new B(); delete b; }
Re: crash on args.getopt
But is it good practice to fail with exception during passing unknown parameters? Maybe std.getopt.config.passThrough should be as default? I really can't remember Apps that crush if pass to in unknown parameters.
Re: What to do with InvalidMemoryOperationError
On Sunday, 25 January 2015 at 00:44:07 UTC, Vladimir Panteleev wrote: I created a wiki page which I hope will help you solve this problem: http://wiki.dlang.org/InvalidMemoryOperationError Hope this helps. Great! Thanks!
Re: crash on args.getopt
On 2015-01-25 at 11:42, Tobias Pankrath wrote: On Sunday, 25 January 2015 at 10:21:34 UTC, Suliman wrote: But is it good practice to fail with exception during passing unknown parameters? Maybe std.getopt.config.passThrough should be as default? I really can't remember Apps that crush if pass to in unknown parameters. Almost all programs fail with an error message, if you pass unknown parameter. Just catch that exception. It's much better to fail up front than to create the illusion that everything is fine after the user has mistyped one of the parameters. Let's say foo a b copies from a to b, but foo --reverse a b does the opposite. Then, when someone types for example foo --revrse a b, and it is silently accepted, the program does exactly the opposite of what the user expects! A side note: GTK applications accept extra parameters used to initialize GTK, but it is not passThrough. What really happens is that the app calls gtk_init(argc, argv) (or Main.init(args) in case of GtkD) before it starts parsing arguments on its own. The call to gtk_init removes the options recognized by GTK from the list of program arguments, and this filtered array can be then processed in a normal way -- which means that whichever parameters are still left unrecognised, the program should fail with an error message.
Re: using the full range of ubyte with iota
On Sunday, 25 January 2015 at 10:42:51 UTC, bearophile wrote: Vlad Levenfeld: What's this about !`[]` and std.range.uniform?? It's not in the documentation. It's an enhancement I have proposed. Hm. I had more something in mind like paramCast - a kind of big scissors that cut everything a function is called with to the size it can cope with, so replacing map!fn not with map!(x = fn(cast(ParameterTypeTuple!fn[0])x) but instead with map!(paramCast!fn) Because this is useful in more situations, e.g. in every place where you know the values would fit into the parameter (and for a single call would use a cast). But so far I couldn't manage to make this work :-/
Re: using the full range of ubyte with iota
On Sunday, 25 January 2015 at 12:25:35 UTC, Dominikus Dittes Scherkl wrote: map!(x = fn(cast(ParameterTypeTuple!fn[0])x) but instead with map!(paramCast!fn) Because this is useful in more situations, e.g. in every place where you know the values would fit into the parameter (and for a single call would use a cast). But so far I couldn't manage to make this work :-/ http://dpaste.dzfl.pl/07b1fa3c2dad
Re: using the full range of ubyte with iota
On Sunday, 25 January 2015 at 13:03:16 UTC, bearophile wrote: Dominikus Dittes Scherkl: Because this is useful in more situations, Right, but it's still a cast. And in D you want to minimize the number of usages of casts. The proposed syntax iota![] is cast-safe. I don't case too much, if I have ensured the cast is safe by constraints beforehand. I need to cast often anyway, because I work with small types and most operators permanently change everything to int, especially the bit-operations for which a signed type makes no sense at all: ubyte x = 50; auto y = x 0x11; // y is int! I hate that! even if I use unsigned literals: auto z = x 0x12u; // z is uint - better but still bad. More so as should result in the smaller of the two types!! But I need not even use literals (which unfortunately cannot be makred as ubyte or short). Look at this: auto x2 = (x4) | (x4); // swap nibbles - but result in an int!
Re: Link errors with curl, libevent, OpenSSL
On Sunday, 25 January 2015 at 15:11:33 UTC, AndyC wrote: On Sunday, 25 January 2015 at 05:48:26 UTC, Vladimir Panteleev wrote: On my Ubuntu Server, I can't link any D program which uses libraries other than Phobos. Example: // import std.net.curl; import std.stdio; void main() { writeln(get(dlang.org)); } // dlang@k3:~/2015-01-25$ dmd -L-lcurl test.d /usr/local/lib/x86_64-linux-gnu/libphobos2.a(curl.o): In function `_D3std3net4curl4HTTP19_sharedStaticCtor34FZv': /usr/local/src/phobos/std/net/curl.d:2503: undefined reference What weirdness has Ubuntu done that this doesn't work? I'm running Slackware and just tried your example and it works fine. Does Ubuntu have developer curl packages as well as regular curl packages? Maybe libcurl-dev package? -Andy Yep, Ubuntu bug: https://bugs.launchpad.net/ubuntu/+source/curl/+bug/1001576 -Andy
Re: Conflicts with Import error - New to D, trying to build a new project
Thanks. I didn't realize that could conflict. On Sunday, 25 January 2015 at 21:22:50 UTC, Ali Çehreli wrote: On 01/25/2015 11:30 AM, Gan wrote: Here's a screenshot: http://cl.ly/image/2n282v0B1X2M The error is: /Users/Matt/Projects/spacecraft/source/Game/Game.d(0,0): Error: class Game.Game.Game conflicts with import Game.Game.Game at source/Game/Game.d(2) (spacecraft) I figure it's because I did imports wrong or something. I'm still very new to D. Can anyone help? The problem is with having three constructs with the same name: package, module, and class. I would use lowercase for package, and module names, and differentiate between the package and the module: .../source/foogame/game.d module foogame.game; class Game { // ... } Ali
Re: core.exception.InvalidMemoryOperationError@(0)
On 01/25/2015 02:06 PM, Bayan Rafeh wrote: is invariant() called during the destruction phase? Something is fishy. import std.stdio; void main(){ writeln(entered main); auto a = new A(); writeln(leaving main); } class A { File file; this() { writeln(this); } ~this() { writeln(~this); } invariant() { writeln(invariant); } } The program produces the following output: entered main this invariant leaving main invariant invariant-- ? ~this invariant-- ? Removing the File member changes the output. Now two of the invariant calls are missing: entered main this invariant leaving main invariant ~this However, the last invariant is still there and I think by design: The destructor should see a valid state. Ali
Re: core.exception.InvalidMemoryOperationError@(0)
On Sunday, 25 January 2015 at 22:46:56 UTC, Ali Çehreli wrote: On 01/25/2015 02:06 PM, Bayan Rafeh wrote: is invariant() called during the destruction phase? Something is fishy. import std.stdio; void main(){ writeln(entered main); auto a = new A(); writeln(leaving main); } class A { File file; this() { writeln(this); } ~this() { writeln(~this); } invariant() { writeln(invariant); } } The program produces the following output: entered main this invariant leaving main invariant invariant-- ? ~this invariant-- ? Removing the File member changes the output. Now two of the invariant calls are missing: entered main this invariant leaving main invariant ~this However, the last invariant is still there and I think by design: The destructor should see a valid state. Ali Could this be a bug in D?
Re: Turning Executable into Application?
On Monday, 26 January 2015 at 03:36:32 UTC, Gan wrote: With Xamarin Studio I create a D project and run it. It runs an Executable Unix file through the terminal. How can I turn that into an Application that doesn't open the Terminal? Thanks. Have you tried running your executable from the command line? I suspect Xamarin is just opening a terminal for you as a convenience.
Question about Allocating
I've been working on my game and am getting some pretty gnarly memory problems. I think it's how I'm allocating. Sometimes when I use variables I can do Color(255, 255, 255). But why is that different than new Color(255, 255, 255)? Same when I'm making arrays. new int[](0) vs []. What's the difference?
vibe.d error
dub init name vibe.d cd name dub Results in Fetching libevent 2.0.1+2.0.16... Error executing command upgrade: Failed to download http://code.dlang.org/packages/libevent/2.0.1%252B2.0.16.zip: 404 Not Found I'm not sure if the error is the file not being there or dub looking there. Is there a workaround for this? Thanks
Re: using the full range of ubyte with iota
On Sun, 25 Jan 2015 14:11:09 +, Dominikus Dittes Scherkl wrote: On Sunday, 25 January 2015 at 13:03:16 UTC, bearophile wrote: Dominikus Dittes Scherkl: Because this is useful in more situations, Right, but it's still a cast. And in D you want to minimize the number of usages of casts. The proposed syntax iota![] is cast-safe. I don't case too much, if I have ensured the cast is safe by constraints beforehand. I need to cast often anyway, because I work with small types and most operators permanently change everything to int, especially the bit-operations for which a signed type makes no sense at all: ubyte x = 50; auto y = x 0x11; // y is int! I hate that! even if I use unsigned literals: auto z = x 0x12u; // z is uint - better but still bad. More so as should result in the smaller of the two types!! But I need not even use literals (which unfortunately cannot be makred as ubyte or short). Look at this: auto x2 = (x4) | (x4); // swap nibbles - but result in an int! this is true for C and C++ too, as all three languages doing integer promotion. the only difference is that D forbids potentially lossy assigns. you best bet is to not use `auto`, but specify required type explicitly. or use ints/uints and cast to bytes only when it is necessary. signature.asc Description: PGP signature
Re: Sqlite
I'd like to vary the query based on input but if I try to move the string out of the sqlite3_exec call like this: string sqlStatement = CREATE TABLE people(id INT PRIMARY KEY NOT NULL, surname TEXT NOT NULL);; result = sqlite3_exec(db, sqlStatement, aCallback, null, msg); ...it won't compile: Error: function etc.c.sqlite3.sqlite3_exec (sqlite3*, const(char)* sql,... is not callable using argument types (sqlite3*, string,... I can assign using: const char *sqlStatement = CREATE TABLE... So how do I get a constant character pointer that can be modified at runtime? Paul
Re: Sqlite
On Sunday, 25 January 2015 at 18:15:21 UTC, Paul wrote: I'd like to vary the query based on input but if I try to move the string out of the sqlite3_exec call like this: string sqlStatement = CREATE TABLE people(id INT PRIMARY KEY NOT NULL, surname TEXT NOT NULL);; result = sqlite3_exec(db, sqlStatement, aCallback, null, msg); ...it won't compile: Error: function etc.c.sqlite3.sqlite3_exec (sqlite3*, const(char)* sql,... is not callable using argument types (sqlite3*, string,... I can assign using: const char *sqlStatement = CREATE TABLE... So how do I get a constant character pointer that can be modified at runtime? Paul Only string literals convert to const(char)*, because only for them it is guaranteed that they are null terminated. For everything else use toStringz.
Re: core.exception.InvalidMemoryOperationError@(0)
On Sun, 25 Jan 2015 08:41:24 +, Bayan Rafeh wrote: I tried what you said and I think I see the problem. I managed to create an example program that duplicates the problem: import std.stdio; class A { string path; this(string p) { path = p; } ~this() { } void a(){} void b(){} } class B { A a; this() { this.a = new A(laladiv); } ~this() { delete a; } } void main() { B a = new B(); B b = new B(); delete b; } The solution was just to remove the delete a from the destructor if someone comes across this later. Could someone tell me why though? there is no guarantees on destruction order. and GC will not nullify any references to collected data. so, `a` can be already collected and finalized when `B.~this()` is called. yet reference is still there, so `delete a;` will try to delete already dead object. this will lead to crash. without precise GC collector is not able to automatically nullify all dead references. and even if there will be such possibility, it can slow down collections alot (GC will nullifying alot of references that aren't used anyway), so i don't think that it do nullifying. there is a simple rule: dtor should not touch GC-managed resources. this will not give you predictable destruction order (that's why most people try to manually delete something in dtor), and this simply will not work at all. if you want predictable destruction order, don't use GC at all, use manual memory management. it doesn't matter which hack you will invent to force destruction order, any hack will either be very fragile, or will not work. this is due to nature of GC-manged memory. so: don't use GC-managed resources in dtors. don't use in any way -- this including accessing 'em. i.e. reading `a.path` in dtor is invalid too. it will not necessarily crash, but it's the source of use after free error. and don't even think that you can trick GC using checks from `core.memory`! this will not work too. sure, you can check if memory used by `a` is still alive, but that memory can be used by completely different object! tl;dr: 1. don't use GC-managed objects in dtors. not even try to access 'em. 2. don't try to trick GC. either don't use it, or cooperate with it. signature.asc Description: PGP signature
Re: Sqlite
On Sunday, 25 January 2015 at 18:19:47 UTC, Tobias Pankrath wrote: Only string literals convert to const(char)*, because only for them it is guaranteed that they are null terminated. For everything else use toStringz. So, as a trivial example, is this how it's done?: string semiC = ;; const char *sqlStatement = toStringz(CREATE TABLE people(id INT PRIMARY KEY NOT NULL, surname TEXT NOT NULL)~semiC); Seems rather ugly but I guess it's a result of interfacing with C...
Re: core.exception.InvalidMemoryOperationError@(0)
On Mon, 26 Jan 2015 05:25:48 +, Bayan Rafeh wrote: There are 2 problems here: 1. By definition, after the destructor is called the object state is destroyed. It makes no sense to check the invariant after the destructor is called because there is no state for us to check. i agree that calling invariant after destruction is invalid. i believe that this is a bug. 2. Invariants theoretically describe the legal states the object can be in which includes variables that are GC managed, therefore I should be able to check the invariant on GC managed objects as well. What's the point of having this feature if I can't even check the invariants of a simple data structure like a set, let alone classes involving files? checking something that is not owned by an object is invalid. invariants MUST NOT be dependent on external data or system state. invariants that tries to check for GC objects ARE dependent of external state. let alone invariants that checking for files, which can be removed while the object is still alive. object can own another object, but it can't own another object *state*. if you want to check something that involves checking something like that, you should use `assert()`s in function body and/or in/out function parts. you are trying to use invariants for the things that invariants can't (and must not) check. invariants are meant for checking *internal* *object* *consistency*. NOT correctness. NOT applicability. ONLY consistency. object can be in inapplicable state, but still consistent. signature.asc Description: PGP signature
Re: Turning Executable into Application?
On Monday, 26 January 2015 at 06:37:34 UTC, tcak wrote: On Monday, 26 January 2015 at 03:36:32 UTC, Gan wrote: With Xamarin Studio I create a D project and run it. It runs an Executable Unix file through the terminal. How can I turn that into an Application that doesn't open the Terminal? Thanks. I use MonoDevelop. I haven't tried that but in Project Options (Not Solution Options), there is a checkbox saying Run on External Console. Uncheck that one maybe. As far as I understand, you want to make a GUI program by saying application. That's it! Thank you!
Turning Executable into Application?
With Xamarin Studio I create a D project and run it. It runs an Executable Unix file through the terminal. How can I turn that into an Application that doesn't open the Terminal? Thanks.
Re: core.exception.InvalidMemoryOperationError@(0)
the thing is that your invariant is not a correct invariant at all. invariants are meant to check *internal* object consistency, not external conditions. compiler is free to call invariant block at any time after object is properly initialised (i.e. after ctor is complete) and is not executing member method. so it's perfectly legal to call invariant before dtor, as you should not check anything that is not belonging to the object itself in in. in other words: you can't check any contents of any reference-typed variables in your invariant block. `string` is reference-typed (it's a dynamic array managed by GC in your case), so you can't check it contents in invariant. you CAN, however, use `f` methods in your invariant, as `f` is a struct which lives *inside* your object, and not a reference var. but note that it's a bad practice anyway, as some struct can use some GC- managed objects which can't be safely used in invariant block. There are 2 problems here: 1. By definition, after the destructor is called the object state is destroyed. It makes no sense to check the invariant after the destructor is called because there is no state for us to check. 2. Invariants theoretically describe the legal states the object can be in which includes variables that are GC managed, therefore I should be able to check the invariant on GC managed objects as well. What's the point of having this feature if I can't even check the invariants of a simple data structure like a set, let alone classes involving files?
Re: Difference between concatenation and appendation
On Monday, 26 January 2015 at 01:57:04 UTC, bearophile wrote: Laeeth Isharc: I think concatenation and append are used as synonyms (the same meaning is meant). a~=b or a=a~b a=a~b always allocates a new array, while a~=b sometimes re-allocates in place. Bye, bearophile Perfect! Thank you. I'll scribble your quote you in the margin of my TDPL book.
Re: Difference between concatenation and appendation
On Monday, January 26, 2015 01:17:15 WhatMeWorry via Digitalmars-d-learn wrote: Ok, I just made up that word. But what is the difference between appending and concatenating? Page 100 of TPDL says The result of the concatenation is a new array... and the section on appending talks about possibly needing expansion and reallocation of memory. But I still don't feel like I have a grasp on the subtleties between them. Can someone give a short and sweet rule of thumb? It might be so obvious that I'll regret posting this. ~ is the concatenation operator. ~= is the append operator. ~ takes two objects (most typically arrays, but user-defined types can define the same operators) and returns a new one which contains the data from the first one followed by the data from the second without affecting either object. ~= takes two objects and adds the data from the second one to the end of the first one (without affecting the second object). ~ is forced to allocate, because it's creating a new object. Whether ~= allocates depends on the data involved and the implementation, though ideally, it would avoid allocation if it can. In the case of arrays rather than user-defined objects, ~= is managed by the GC. So, whether ~= allocates or not depends on whether there's room/capacity in the block of memory that the array is a slice of after the array. If there's enough room, then it will just increase the size of the array, and put the new data in that memory, but if there isn't enough room (e.g. because the memory block doesn't have enough room or because another array refers to a pointer farther in the block of memory than the one being appended to), then a new block of memory is allocated, the data is then assigned to there, and the array is changed to be a slice of that memory block. For user-defined types, it depends entirely on how ~= is implemented, but it's probably going to either be doing something similar or be forced to reallocate every time. In any case, the main difference between ~ and ~= is that ~ creates a new array or object _every_ time, and ~= mutates the first argument and will generally only result in an allocation if it has to (particularly if you're dealing with arrays). I'd sugges that you read this article on D arrays: http://dlang.org/d-array-article.html It mixes up its terminology a bit with regards to dynamic arrays (the language considers int[] to be a dynamic array, whereas the article refers to the GC-allocated block of memory that the array refers to as being the dynamic array), but it should definitely clarify a lot about D arrays for you. - Jonathan M Davis
Re: Turning Executable into Application?
On Monday, 26 January 2015 at 03:36:32 UTC, Gan wrote: With Xamarin Studio I create a D project and run it. It runs an Executable Unix file through the terminal. How can I turn that into an Application that doesn't open the Terminal? Thanks. I use MonoDevelop. I haven't tried that but in Project Options (Not Solution Options), there is a checkbox saying Run on External Console. Uncheck that one maybe. As far as I understand, you want to make a GUI program by saying application.
Re: Link errors with curl, libevent, OpenSSL
On Sunday, 25 January 2015 at 05:48:26 UTC, Vladimir Panteleev wrote: On my Ubuntu Server, I can't link any D program which uses libraries other than Phobos. Example: // import std.net.curl; import std.stdio; void main() { writeln(get(dlang.org)); } // dlang@k3:~/2015-01-25$ dmd -L-lcurl test.d /usr/local/lib/x86_64-linux-gnu/libphobos2.a(curl.o): In function `_D3std3net4curl4HTTP19_sharedStaticCtor34FZv': /usr/local/src/phobos/std/net/curl.d:2503: undefined reference to `curl_version_info' /usr/local/lib/x86_64-linux-gnu/libphobos2.a(curl.o): In function `_D3std3net4curl4Curl19_sharedStaticCtor35FZv': /usr/local/src/phobos/std/net/curl.d:3497: undefined reference to `curl_global_init' /usr/local/lib/x86_64-linux-gnu/libphobos2.a(curl.o): In function `_D3std3net4curl4Curl19_sharedStaticDtor36FZv': /usr/local/src/phobos/std/net/curl.d:3503: undefined reference to `curl_global_cleanup' [...] collect2: error: ld returned 1 exit status --- errorlevel 1 The library (.a and .so) is installed and DMD passes -lcurl to gcc. This is what DMD runs: gcc test.o -o test -m64 -lcurl -L/usr/local/lib/x86_64-linux-gnu -Xlinker --export-dynamic -l:libphobos2.a -lpthread -lm -lrt I got the above program to build by editing /etc/dmd.conf and adding -L-l:libphobos2.a -L-lcurl to DFLAGS. However, this doesn't help when linking with other D libraries, e.g. when using Dub. I believe this problem is documented here: https://issues.dlang.org/show_bug.cgi?id=7044 https://issues.dlang.org/show_bug.cgi?id=12572 I don't see a workaround that would apply to dub, though. Is there a fix or workaround? I think this can be fixed in Dub to make it pass the libraries in the correct order, but I don't normally use Dub so I'm not sure. I sort of need this to be able to work on dlang.org - some functionality is only provided by posix.mak, which doesn't work under Cygwin. What weirdness has Ubuntu done that this doesn't work? I'm running Slackware and just tried your example and it works fine. Does Ubuntu have developer curl packages as well as regular curl packages? Maybe libcurl-dev package? -Andy
Re: using the full range of ubyte with iota
On Sunday, 25 January 2015 at 12:56:14 UTC, Tobias Pankrath wrote: On Sunday, 25 January 2015 at 12:25:35 UTC, Dominikus Dittes Scherkl wrote: map!(x = fn(cast(ParameterTypeTuple!fn[0])x) but instead with map!(paramCast!fn) Because this is useful in more situations, e.g. in every place where you know the values would fit into the parameter (and for a single call would use a cast). But so far I couldn't manage to make this work :-/ http://dpaste.dzfl.pl/07b1fa3c2dad Hey cool. With unary function I can even remove the string and mixin magic: template paramCast(alias fn) { ReturnType!fn paramCast(T)(T x) { return fn(cast(ParameterTypeTuple!fn[0])x); } } Many Thanks!
unittest with Visual D
I finaly got managed to install Visual D on my Windows PC (thanks to the new community version of Visual Studio), but the cool point Compile and Run seems to have a problem with some of my unittests: I get the error template instance xy is not defined if a specific instantiation is not used in my main program. But shouldn't the compiler build all instantiations used within a unittest?!? What am I missing?
Suggestions on what to use for testing?
Just doing my first moves around with D and I realize that I want to structure my tests. Wondering what you are using as a test runner / test framework on top of plain unittest support in D itself? So far I am ending up with adding comments into my code to structure things: https://github.com/johbo/photo-sort/blob/master/source/store.d#L85 It suggest to me that I want something like a setup/teardown mechanism together with a way to give names to tests. Saw that there are already a few suggestions in the wiki: http://wiki.dlang.org/Libraries_and_Frameworks#Unit_Testing_Framework So that's were I will continue to explore things. Still if someone already tried those out, sharing conclusions would be appreciated ;-)
Re: using the full range of ubyte with iota
Dominikus Dittes Scherkl: Because this is useful in more situations, Right, but it's still a cast. And in D you want to minimize the number of usages of casts. The proposed syntax iota![] is cast-safe. Bye, bearophile
Re: Extracting Structure from HTML using Adam's dom.d
Adam, I understood how to select URLs, but how extract values of attributes from such selection? a href=/ class=post-tag title=show questions tagged 'javascript' rel=somedata I need extract data inside rel (somedata)
Re: Conflicts with Import error - New to D, trying to build a new project
On 01/25/2015 11:30 AM, Gan wrote: Here's a screenshot: http://cl.ly/image/2n282v0B1X2M The error is: /Users/Matt/Projects/spacecraft/source/Game/Game.d(0,0): Error: class Game.Game.Game conflicts with import Game.Game.Game at source/Game/Game.d(2) (spacecraft) I figure it's because I did imports wrong or something. I'm still very new to D. Can anyone help? The problem is with having three constructs with the same name: package, module, and class. I would use lowercase for package, and module names, and differentiate between the package and the module: .../source/foogame/game.d module foogame.game; class Game { // ... } Ali
Re: using the full range of ubyte with iota
On Sun, 25 Jan 2015 20:42:47 +, Dominikus Dittes Scherkl wrote: But in a function you need the cast anyway: ubyte swapNibbles(ubyte x) { return (x4) | (x4); } // compiler not happy sure, it can't be happy, as `x` is promoted to int in the expression, so the expression result is `int`. better range analysis can prove that the resuit can be fit in `ubyte`, of course. or you can do `0xff` -- the compiler is intelligent enough to see that this fits to ubyte too. or if you index with a long, even after explicit check: int foo(ulong x) { int[10] a; return (x 10) ? a[x] : 0; // cannot index with long } why do you index with `ulong`s in the first place? there is ugly `size_t` type for this. anyway, what you talking about is a missing integer range analysis in complier. i'm not sure that it worth adding, as it slows down compilation and hiding some potentially bad code. i can grep for `cast`s to see where author is playing with fire, but i can't grep for range analysis. ;-) p.s. `a[xsize_t.max]` works fine in your sample. and to be honest, i prefer either this, or `cast` -- any form of explicit type transformation. p.p.s. what is bad is that compiler happily accepts this: int foo (int x) { int[10] a; return a[x]; } WTF?! why, in the name of Ruler of Hell, array indexing with int doesn't generate any warning?! D design decision to silently allow conversion of `int` to `uint`/`ulong` is conceptually flawed. but this is one of the things that will never be fixed, so we have to live with it. signature.asc Description: PGP signature
Re: core.exception.InvalidMemoryOperationError@(0)
On Sunday, 25 January 2015 at 19:15:54 UTC, ketmar wrote: On Sun, 25 Jan 2015 08:41:24 +, Bayan Rafeh wrote: I tried what you said and I think I see the problem. I managed to create an example program that duplicates the problem: import std.stdio; class A { string path; this(string p) { path = p; } ~this() { } void a(){} void b(){} } class B { A a; this() { this.a = new A(laladiv); } ~this() { delete a; } } void main() { B a = new B(); B b = new B(); delete b; } The solution was just to remove the delete a from the destructor if someone comes across this later. Could someone tell me why though? there is no guarantees on destruction order. and GC will not nullify any references to collected data. so, `a` can be already collected and finalized when `B.~this()` is called. yet reference is still there, so `delete a;` will try to delete already dead object. this will lead to crash. without precise GC collector is not able to automatically nullify all dead references. and even if there will be such possibility, it can slow down collections alot (GC will nullifying alot of references that aren't used anyway), so i don't think that it do nullifying. there is a simple rule: dtor should not touch GC-managed resources. this will not give you predictable destruction order (that's why most people try to manually delete something in dtor), and this simply will not work at all. if you want predictable destruction order, don't use GC at all, use manual memory management. it doesn't matter which hack you will invent to force destruction order, any hack will either be very fragile, or will not work. this is due to nature of GC-manged memory. so: don't use GC-managed resources in dtors. don't use in any way -- this including accessing 'em. i.e. reading `a.path` in dtor is invalid too. it will not necessarily crash, but it's the source of use after free error. and don't even think that you can trick GC using checks from `core.memory`! this will not work too. sure, you can check if memory used by `a` is still alive, but that memory can be used by completely different object! tl;dr: 1. don't use GC-managed objects in dtors. not even try to access 'em. 2. don't try to trick GC. either don't use it, or cooperate with it. All right, I removed all my destructors(turns out I don't really need them), but I'm still running into this very same error. This is another problematic example program: import std.stdio; void main(){ auto a = new A(/tmp/invalid); } class A { File f; string path; this(string path) { this.path = path; //f = File(path, r); } invariant() { File test = File(path, r); } } is invariant() called during the destruction phase?
Re: Extracting Structure from HTML using Adam's dom.d
On Sunday, 25 January 2015 at 21:24:06 UTC, Suliman wrote: I need extract data inside rel (somedata) string s = element.rel;
Re: core.exception.InvalidMemoryOperationError@(0)
On Sun, 25 Jan 2015 22:06:26 +, Bayan Rafeh wrote: This is another problematic example program: import std.stdio; void main(){ auto a = new A(/tmp/invalid); } class A { File f; string path; this(string path) { this.path = path; //f = File(path, r); } invariant() { File test = File(path, r); } } is invariant() called during the destruction phase? the thing is that your invariant is not a correct invariant at all. invariants are meant to check *internal* object consistency, not external conditions. compiler is free to call invariant block at any time after object is properly initialised (i.e. after ctor is complete) and is not executing member method. so it's perfectly legal to call invariant before dtor, as you should not check anything that is not belonging to the object itself in in. in other words: you can't check any contents of any reference-typed variables in your invariant block. `string` is reference-typed (it's a dynamic array managed by GC in your case), so you can't check it contents in invariant. you CAN, however, use `f` methods in your invariant, as `f` is a struct which lives *inside* your object, and not a reference var. but note that it's a bad practice anyway, as some struct can use some GC- managed objects which can't be safely used in invariant block. signature.asc Description: PGP signature
Re: Difference between concatenation and appendation
On Monday, 26 January 2015 at 01:17:17 UTC, WhatMeWorry wrote: Ok, I just made up that word. But what is the difference between appending and concatenating? Page 100 of TPDL says The result of the concatenation is a new array... and the section on appending talks about possibly needing expansion and reallocation of memory. But I still don't feel like I have a grasp on the subtleties between them. Can someone give a short and sweet rule of thumb? It might be so obvious that I'll regret posting this. Thanks. At the risk of the blind leading the blind (I am no expert), I think concatenation and append are used as synonyms (the same meaning is meant). a~=b or a=a~b If there isn't enough space then the whole array is reallocated. You can see this/change this property by reading capacity or calling reserve. If you want to do lots of appends / concatenates then use appender in std.array which is faster and more efficient.
Re: Difference between concatenation and appendation
On Monday, 26 January 2015 at 01:57:04 UTC, bearophile wrote: Laeeth Isharc: I think concatenation and append are used as synonyms (the same meaning is meant). a~=b or a=a~b a=a~b always allocates a new array, while a~=b sometimes re-allocates in place. Bye, bearophile Thanks. That makes sense.
Re: core.exception.InvalidMemoryOperationError@(0)
On Sun, 25 Jan 2015 22:06:26 +, Bayan Rafeh wrote: p.s. yet creating new `File` in invariant is wrong nevertheless, as it changes the program state. invariant checks SHOULD NEVER CHANGE THE PROGRAM STATE. signature.asc Description: PGP signature
Difference between concatenation and appendation
Ok, I just made up that word. But what is the difference between appending and concatenating? Page 100 of TPDL says The result of the concatenation is a new array... and the section on appending talks about possibly needing expansion and reallocation of memory. But I still don't feel like I have a grasp on the subtleties between them. Can someone give a short and sweet rule of thumb? It might be so obvious that I'll regret posting this. Thanks.
Re: Difference between concatenation and appendation
On Monday, 26 January 2015 at 01:17:17 UTC, WhatMeWorry wrote: Ok, I just made up that word. But what is the difference between appending and concatenating? Page 100 of TPDL says The result of the concatenation is a new array... and the section on appending talks about possibly needing expansion and reallocation of memory. But I still don't feel like I have a grasp on the subtleties between them. Can someone give a short and sweet rule of thumb? It might be so obvious that I'll regret posting this. Thanks. I'm no expert, so take what I say with a grain of salt. That said, here is my understanding: When you append to an array with ~=, it attempts to reallocate the array in-place, meaning it allocates on top of the already used space, but grabs some more space past the end of the array. If there isn't enough space after the array then obviously it can't do that, so it allocates memory somewhere else that it can fit and then it copies the contents of the array to the new location. If you were to do myArray = myArray ~ moreStuff; I assume this is no different from ~=. Conceptually ~= is just syntactic sugar in the same way that += or -= is, you are just doing a concatenation and then updating the array to point to the new result. The fact that it can reallocate in place if there is enough space is just like an optimization, in my mind.
Re: Difference between concatenation and appendation
Laeeth Isharc: I think concatenation and append are used as synonyms (the same meaning is meant). a~=b or a=a~b a=a~b always allocates a new array, while a~=b sometimes re-allocates in place. Bye, bearophile
Re: Linking C library (.dll) to D on windows
On 1/26/2015 5:45 AM, Roman wrote: Stuff: 1. There are C code module.c and module.h 2. MinGW 3. DMD 2.066.1 4. Window 8.1 module.c: #include module.h int add(int a, int b) {return a + b;} module.h: int add(int,int); I want to use function add from D so i call cc -shared module.c -o module.dll Then D code main.d: import std.stdio; extern(C) { int add(int a, int b); } void main() { writefln(From C Dll %d,add(2,3)); } So how i should compile with dmd, to get this work? dmd main.d -L=module.dll prints: OPTLINK (R) for Win32 Release 8.00.15 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html OPTLINK : Error 8: Illegal Filename main,,nul,user32+kernel32/noi=module.dll; ^ --- errorlevel 1 I've tried to found smthing here http://wiki.dlang.org/Compiling_and_linking_with_DMD_on_Windows but dll tutorial is missing So does DMD available to link dll files? Problem #1: linking directly to dlls is not common in the Windows ecosystem. AFAIK, MinGW is the only toolchain that supports that. By default, DMD uses the OPTLINK linker for 32-bit apps and uses the MS linker for 64-bit, neither of which have the ability to link directly with dlls. You need an import library. Problem #2: OPTLINK only understands the OMF format for object files, whereas MinGW and the MS compiler output COFF. So you have three options for linking with 32-bit DMD: * Compile with the Digital Mars C/C++ compiler (DMC) and generate an import library along with the dll. * Compile with another compiler and run implib (part of the free Basic Utilities Package from Digital Mars, downloadable from [1]) on the dll to generate an import library in OMF format. * Load the DLL dynamically, then you don't need an import library. extern( C ) alias addptr = int function(int, int); addptr add; auto handle = LoadLibrary( MyLib.dll ); add = cast( addptr )GetProcAddress( handle, add ); Alternatively, you could compile as 64-bit, generate an import library with the DLL when you compile it with MinGW, and link directly with the import lib (the next version of DMD will support COFF for 32-bit). However, I have had trouble attempting to link static MinGW libraries with 64-bit DMD. Some have worked, some haven't. An import library is not the same and I assume it would work, but I've never tried. Then again, since 64-bit DMD requires the MS toolchain to be installed, another option is to forego MinGW and use the MS compiler instead.
Re: Linking C library (.dll) to D on windows
On 1/26/2015 11:18 AM, Mike Parker wrote: * Compile with another compiler and run implib (part of the free Basic Utilities Package from Digital Mars, downloadable from [1]) on the dll to generate an import library in OMF format. [1] http://www.digitalmars.com/download/freecompiler.html
Linking C library (.dll) to D on windows
Stuff: 1. There are C code module.c and module.h 2. MinGW 3. DMD 2.066.1 4. Window 8.1 module.c: #include module.h int add(int a, int b) {return a + b;} module.h: int add(int,int); I want to use function add from D so i call cc -shared module.c -o module.dll Then D code main.d: import std.stdio; extern(C) { int add(int a, int b); } void main() { writefln(From C Dll %d,add(2,3)); } So how i should compile with dmd, to get this work? dmd main.d -L=module.dll prints: OPTLINK (R) for Win32 Release 8.00.15 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html OPTLINK : Error 8: Illegal Filename main,,nul,user32+kernel32/noi=module.dll; ^ --- errorlevel 1 I've tried to found smthing here http://wiki.dlang.org/Compiling_and_linking_with_DMD_on_Windows but dll tutorial is missing So does DMD available to link dll files?
Conflicts with Import error - New to D, trying to build a new project
Here's a screenshot: http://cl.ly/image/2n282v0B1X2M The error is: /Users/Matt/Projects/spacecraft/source/Game/Game.d(0,0): Error: class Game.Game.Game conflicts with import Game.Game.Game at source/Game/Game.d(2) (spacecraft) I figure it's because I did imports wrong or something. I'm still very new to D. Can anyone help?
Re: PostgreSQL driver
So, it's been about a year since you asked this. Did you ever determine which PostgreSQL library to use? Is there one that makes any more sense than the others?
Re: using the full range of ubyte with iota
On Sunday, 25 January 2015 at 18:59:04 UTC, ketmar wrote: auto x2 = (x4) | (x4); // swap nibbles - but result in an int! this is true for C and C++ too, as all three languages doing integer promotion. the only difference is that D forbids potentially lossy assigns. you best bet is to not use `auto`, but specify required type explicitly. or use ints/uints and cast to bytes only when it is necessary. in normal assignments I never use auto - it's not simpler than writing the type explicit but later makes it more complicated to see what type it is. But in a function you need the cast anyway: ubyte swapNibbles(ubyte x) { return (x4) | (x4); } // compiler not happy or if you index with a long, even after explicit check: int foo(ulong x) { int[10] a; return (x 10) ? a[x] : 0; // cannot index with long } So there are plenty of places in D where cast is necessary but should not be. I think both of above cases should be safe without cast, and enhancing the compilerr that it can handle these cases is more important than a iota![]. Until then I prefer paramCast!fn, because this is more flexible than the iota extension and my code is full of casts anyway.
Re: Link errors with curl, libevent, OpenSSL
On Sunday, 25 January 2015 at 15:23:03 UTC, AndyC wrote: On Sunday, 25 January 2015 at 15:11:33 UTC, AndyC wrote: On Sunday, 25 January 2015 at 05:48:26 UTC, Vladimir Panteleev wrote: On my Ubuntu Server, I can't link any D program which uses libraries other than Phobos. Example: // import std.net.curl; import std.stdio; void main() { writeln(get(dlang.org)); } // dlang@k3:~/2015-01-25$ dmd -L-lcurl test.d /usr/local/lib/x86_64-linux-gnu/libphobos2.a(curl.o): In function `_D3std3net4curl4HTTP19_sharedStaticCtor34FZv': /usr/local/src/phobos/std/net/curl.d:2503: undefined reference What weirdness has Ubuntu done that this doesn't work? I'm running Slackware and just tried your example and it works fine. Does Ubuntu have developer curl packages as well as regular curl packages? Maybe libcurl-dev package? -Andy Yep, Ubuntu bug: https://bugs.launchpad.net/ubuntu/+source/curl/+bug/1001576 Thank you. It looks like this is an incompatibility between DMD and Ubuntu enabling --as-needed. This pointed me in the right direction to find a workaround: https://issues.dlang.org/show_bug.cgi?id=12572#c5
Re: When to use typecons.proxy vs alias this?
On Sunday, 25 January 2015 at 05:57:37 UTC, weaselcat wrote: So the only difference is that proxy doesn't have implicit conversions? Hm. Might be worth pointing out on the docs. I don't think it is the *only* difference - the implementations are very different - but I do think it is the most significant one.