Re: out contract misunderstanding (was: I cannot understand problem with argument of the function)
On Thursday, 19 September 2013 at 01:41:15 UTC, mrd wrote: $ ./bug body, value=2 out contract, value=0 Why argument "value" in contract isn't equal 2 ? Why should it be? value is a mutable argument, and the out contract evaluates it at the return point, which is after it's set to 0. It is no different than using value in the body just before the return point. If you want to preserve the original arguments until the return point, use const and create a mutable duplicate. Ivan Kazmenko.
Re: Mac and Win support
On 2013-09-19 01:05, Jonathan A Dunlap wrote: In D's current status, which OS between the two would you say is 'most' supported? I'm looking at features like parallelism and SIMD. Thanks! I don't if there are any big differences between Windows and Mac OS X in regards those two features. A big difference is that on Windows 32bit the Optlink linker is used. Which is known to cause problems. On Mac OS X and the rest of the Posix platforms the system linker is used. Compiling for 64bit on Windows will uses the Microsoft linker. But the support for the Microsoft tool chain is quite new. -- /Jacob Carlborg
Re: SQLite3 segmentation at prepare statement
On Wednesday, 18 September 2013 at 21:31:00 UTC, Charles Hixson wrote: I'm trying to use SQLite3 in D, but am getting a segmentation fault when I attempt to replace the exec statement with a prepare statement. What am I doing wrong? If the prepare statement is commented out, and the exec statement is uncommented, the program runs successfully. (There's no data yet in the database file.) The test program is: pragma(lib, "sqlite3"); importetc.c.sqlite3; importstd.exception; importstd.stdio; importstd.string; /**int function(void*, int, char**, char**) callback*/ extern(C) intcallback(void* notUsed, int argc, char** argv, char** azColName) { for(int i = 0;i < argc;i++) {printf ("%s = %s\n", azColName[i], argv[i] ? argv[i] : "null");} printf("\n"); return0; } voidmain() {sqlite3*db; intrc; char*zErrMsg=null; sqlite3_stmt**stmt; rc=sqlite3_open (toStringz("data/sqlitetest.db"), &db); if(SQLITE_OK != rc) {printf ("DB create error: %s\n", sqlite3_errmsg(db) ); } stringsql= "create table if not exists wrds (name text primary key, id int)\0"; rc=sqlite3_exec(db, sql.ptr, &callback, cast(void*)0, &zErrMsg); if(SQLITE_OK != rc) {printf ("DB create table error: %s\n", sqlite3_errmsg(db) ); printf("sql = <<%s>>\n", sql); } sql="select * from wrds\0"; rc=sqlite3_prepare(db, toStringz(sql), cast(int)sql.length, stmt, null); //if(SQLITE_OK != rc) //{printf ("DB prepare statement error: %s\n", sqlite3_errmsg(db) ); //printf("sql = <<%s>>\n", sql); //} //rc=sqlite3_step(*stmt); //if(SQLITE_OK != rc) //{printf ("DB statement step error: %s\n", sqlite3_errmsg(db) ); //printf("sql = <<%s>>\n", sql); //} // //rc=sqlite3_exec(db, sql.ptr, &callback, cast(void*)0, &zErrMsg); //if(SQLITE_OK != rc) //{printf ("DB select error: %s\n", sqlite3_errmsg(db) ); //printf("sql = <<%s>>\n", sql); //} // rc=sqlite3_close(db); enforce(rc == SQLITE_OK); } Sorry I'm not a sqlite3 expert, nor do I have access to DMD at the moment so cannot fully test but that sqlite3_stmt** looks wrong, try this: change: --- sqlite3_stmt**stmt; ... rc= sqlite3_prepare(db, toStringz(sql), cast(int)sql.length, stmt, null); ... rc=sqlite3_step(*stmt); --- to: --- sqlite3_stmt*stmt; ... rc= sqlite3_prepare(db, toStringz(sql), cast(int)sql.length, &stmt, null); ... rc=sqlite3_step(stmt); --- I think (from ancient memory) that you also need to clean up the statement with something like: sqlite_finalize(stmt); but don't quote me on that :D
dmd segfaults on nested template instantiation (eg A!(A!(int)) )
I just filed a bug report ( http://d.puremagic.com/issues/show_bug.cgi?id=11067) Is there a workaround that keeps same syntax for user code? Use case: i'm generating those from swig(+modifications to map C++ templates to D templates) so I can't factor the template bodies for different template instantiations into a single definition. A!(A!(int)) detections; struct A(T) if(is(T==int)) {} struct A(T) if(is(T==A!(int))) {}
out contract misunderstanding (was: I cannot understand problem with argument of the function)
(new topic because old is mired in a long and clumsy source code) import std.stdio; static ubyte func( ulong value ) out( arr ) { writeln( "out contract, value=", value ); } body { writeln( "body, value=", value ); ubyte res; value >>= 7; return res; } void main() { func( 2 ); } $ ./bug body, value=2 out contract, value=0 Why argument "value" in contract isn't equal 2 ?
Re: Array length : size_t
On Thu, Sep 19, 2013 at 12:52:55AM +0200, Dicebot wrote: > On Wednesday, 18 September 2013 at 22:20:45 UTC, H. S. Teoh wrote: > >If the C function only accepts int, then just use to!int(array.size). > >If the size overflows int, to() will throw an exception which you can > >handle. This is probably the best you can do anyway, since if the C > >function doesn't take anything bigger than int, then there's no way > >you can pass the real size to it. > > Ah, `to!()` does check valid ranges before conversion? Good to know, > thanks. Yes, it's handled explicitly by the following overload of toImpl() in std.conv: T toImpl(T, S)(S value) if (!isImplicitlyConvertible!(S, T) && (isNumeric!S || isSomeChar!S || isBoolean!S) && (isNumeric!T || isSomeChar!T || isBoolean!T) && !is(T == enum)) { ... } T -- Too many people have open minds but closed eyes.
Mac and Win support
In D's current status, which OS between the two would you say is 'most' supported? I'm looking at features like parallelism and SIMD. Thanks!
Re: Array length : size_t
On Wednesday, 18 September 2013 at 22:20:45 UTC, H. S. Teoh wrote: If the C function only accepts int, then just use to!int(array.size). If the size overflows int, to() will throw an exception which you can handle. This is probably the best you can do anyway, since if the C function doesn't take anything bigger than int, then there's no way you can pass the real size to it. Ah, `to!()` does check valid ranges before conversion? Good to know, thanks.
Re: Array length : size_t
On Wed, Sep 18, 2013 at 10:46:18PM +0200, Namespace wrote: > D's Array length is currently of type size_t, which means on 32 bit > it's an uint and on 64 bit an ulong. This is difficult: What if I > want to give the length of an array as parameter to some C functions > which accepts only an int? > What is the right/safe way to do this? A cast? Or is there something > better? > I like to avoid cast's if they aren't necessary. If the C function only accepts int, then just use to!int(array.size). If the size overflows int, to() will throw an exception which you can handle. This is probably the best you can do anyway, since if the C function doesn't take anything bigger than int, then there's no way you can pass the real size to it. T -- PNP = Plug 'N' Pray
Re: Array length : size_t
On Wednesday, 18 September 2013 at 20:46:21 UTC, Namespace wrote: D's Array length is currently of type size_t, which means on 32 bit it's an uint and on 64 bit an ulong. This is difficult: What if I want to give the length of an array as parameter to some C functions which accepts only an int? What is the right/safe way to do this? A cast? Or is there something better? I like to avoid cast's if they aren't necessary. Perfectly safe way is to do run-time range check followed by a cast. Maybe using a wrapper: auto shrinkTo(Target, Source)(Source source) if (is(Target : Source)) // is implicitly convertable other way around { assert(source <= Target.max); static if (is(typeof(Taget.min))) assert(source >= Target.min); return cast(Target)source; } void main() { import std.stdio; long a = 50; long b = int.max; b++; writeln(shrinkTo!int(a)); writeln(shrinkTo!int(b)); }
SQLite3 segmentation at prepare statement
I'm trying to use SQLite3 in D, but am getting a segmentation fault when I attempt to replace the exec statement with a prepare statement. What am I doing wrong? If the prepare statement is commented out, and the exec statement is uncommented, the program runs successfully. (There's no data yet in the database file.) The test program is: pragma(lib, "sqlite3"); importetc.c.sqlite3; importstd.exception; importstd.stdio; importstd.string; /**int function(void*, int, char**, char**) callback*/ extern(C) intcallback(void* notUsed, int argc, char** argv, char** azColName) { for(int i = 0;i < argc;i++) {printf ("%s = %s\n", azColName[i], argv[i] ? argv[i] : "null");} printf("\n"); return0; } voidmain() {sqlite3*db; intrc; char*zErrMsg=null; sqlite3_stmt**stmt; rc=sqlite3_open (toStringz("data/sqlitetest.db"), &db); if(SQLITE_OK != rc) {printf ("DB create error: %s\n", sqlite3_errmsg(db) );} stringsql= "create table if not exists wrds (name text primary key, id int)\0"; rc=sqlite3_exec(db, sql.ptr, &callback, cast(void*)0, &zErrMsg); if(SQLITE_OK != rc) {printf ("DB create table error: %s\n", sqlite3_errmsg(db) ); printf("sql = <<%s>>\n", sql); } sql="select * from wrds\0"; rc=sqlite3_prepare(db, toStringz(sql), cast(int)sql.length, stmt, null); //if(SQLITE_OK != rc) //{printf ("DB prepare statement error: %s\n", sqlite3_errmsg(db) ); //printf("sql = <<%s>>\n", sql); //} //rc=sqlite3_step(*stmt); //if(SQLITE_OK != rc) //{printf ("DB statement step error: %s\n", sqlite3_errmsg(db) ); //printf("sql = <<%s>>\n", sql); //} // //rc=sqlite3_exec(db, sql.ptr, &callback, cast(void*)0, &zErrMsg); //if(SQLITE_OK != rc) //{printf ("DB select error: %s\n", sqlite3_errmsg(db) ); //printf("sql = <<%s>>\n", sql); //} // rc=sqlite3_close(db); enforce(rc == SQLITE_OK); } -- Charles Hixson
Re: I cannot understand problem with argument of the function
This bug reproducible also without a template: http://pastebin.com/QPvCFYL1 $ ./bug works: Inside of body: value=1 type=ulong Inside of out contract: value=1 type=ulong result=[1] not works: Inside of body: value=300 type=ulong Inside of out contract: value=2 type=ulong result=[172, 2]
Array length : size_t
D's Array length is currently of type size_t, which means on 32 bit it's an uint and on 64 bit an ulong. This is difficult: What if I want to give the length of an array as parameter to some C functions which accepts only an int? What is the right/safe way to do this? A cast? Or is there something better? I like to avoid cast's if they aren't necessary.
Re: I cannot understand problem with argument of the function
On Wednesday, 18 September 2013 at 10:59:11 UTC, monarch_dodra wrote: On Wednesday, 18 September 2013 at 10:37:29 UTC, mrd wrote: Is the contract does not uses its own version of arguments? What is the point of passing earlier changed arguments into contract block? That's a good question. I'll raise it on the main boards. Here is simplified file that reproduces this bug (or not bug): http://pastebin.com/0QRZcts8 $ ./bug Inside of body: value=300 type=ulong Inside of out contract: value=2 type=ulong result=[172, 2]
Re: Odd compiler complaints with import declarations
Sorry this is correct http://forum.dlang.org/thread/dupcnblrqhesdvwye...@forum.dlang.org
Re: Odd compiler complaints with import declarations
See also http://forum.dlang.org/thread/dupcnblrqhesdvwyeuaa@forum.dlang.orgOn Friday, 13
Re: GC.collect bug ?
On Tuesday, 17 September 2013 at 11:14:10 UTC, Temtaime wrote: I cannot use the delete/destroy. I want to call dtor at all unreferenced objects. Manual from Dlang size says that GC.collect triggers a full collection. But it doesn't. It is not possible by design as GC is not deterministic. Destructors are not guaranteed to be ever run at all. You need to change your program architecture if you rely on it right now.
Re: surrounded type modifier
On Wednesday, 18 September 2013 at 14:23:25 UTC, Namespace wrote: Should I open an enhancement report? Of course you are always free to open enhancement reports.
Re: surrounded type modifier
On Wednesday, 18 September 2013 at 14:17:04 UTC, Maxim Fomin wrote: On Wednesday, 18 September 2013 at 13:23:10 UTC, Namespace wrote: Code: const { /// [1] int a = 3; } void main() { const { /// [2] int b = 4; } } Why is [1] allowed, but not [2]? Citing grammar: FunctionBody: BlockStatement BodyStatement InStatement BodyStatement OutStatement BodyStatement InStatement OutStatement BodyStatement OutStatement InStatement BodyStatement BlockStatement: { } { StatementList } As you can see there is no room for attributes. Why dmd does not support attributes here is separate question - probably because such construct would be confused with lambda, but this is not a serious reason. Should I open an enhancement report?
Re: surrounded type modifier
On Wednesday, 18 September 2013 at 13:23:10 UTC, Namespace wrote: Code: const { /// [1] int a = 3; } void main() { const { /// [2] int b = 4; } } Why is [1] allowed, but not [2]? Citing grammar: FunctionBody: BlockStatement BodyStatement InStatement BodyStatement OutStatement BodyStatement InStatement OutStatement BodyStatement OutStatement InStatement BodyStatement BlockStatement: { } { StatementList } As you can see there is no room for attributes. Why dmd does not support attributes here is separate question - probably because such construct would be confused with lambda, but this is not a serious reason.
Re: surrounded type modifier
On Wednesday, 18 September 2013 at 13:42:37 UTC, bearophile wrote: Namespace: Code: const { /// [1] int a = 3; } void main() { const { /// [2] int b = 4; } } Why is [1] allowed, but not [2]? Think about what this does: void main() { { int b = 4; } } It creates a new scope inside the function. How do you tell apart the syntax to create a new scope from having a "group tagging" as in the global case? Bye, bearophile If a type modifier is in front of '{' it's a group tagging, otherwise a scope.
Re: surrounded type modifier
Same thing with debug: { // scope code } debug { // debug code }
Re: using scons on 64-bit platform, with gdc
On Wednesday, 18 September 2013 at 07:09:27 UTC, eles wrote: import os env = Environment(ENV = os.environ) gcc -o test01 -m32 test01.o -L/usr/lib -lphobos2 -lpthread -lm Related, why the scons is passing the -L/usr/lib to the gcc, while the LD_LIBRARY_PATH variable of my bash shell is rather: /opt/gdc-4.9/lib/../lib64 This provides a bad version of lib(g)phobos.a. The verbose invocation of gcc (no -L parameter), that is: gcc -v -o test01 -m64 test01.o -lgphobos2 -lpthread -lm correctly specifies: LIBRARY_PATH=/opt/gdc-4.9/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/:/opt/gdc-4.9/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib64/:/lib/x86_64-linux-gnu/:/lib/../lib64/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib64/:/opt/gdc-4.9/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../:/lib/:/usr/lib/ and finds the libgphobos.a from: /opt/gdc-4.9/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib64/ which, indeed, is the correct version. Note that I have two installations of gdc, but the PATH of /opt/gdc-4.9/bin preceded the /usr/bin: $ which -a gcc /opt/gdc-4.9/bin/gcc /usr/bin/gcc
Re: surrounded type modifier
Namespace: Code: const { /// [1] int a = 3; } void main() { const { /// [2] int b = 4; } } Why is [1] allowed, but not [2]? Think about what this does: void main() { { int b = 4; } } It creates a new scope inside the function. How do you tell apart the syntax to create a new scope from having a "group tagging" as in the global case? Bye, bearophile
surrounded type modifier
Code: const { /// [1] int a = 3; } void main() { const { /// [2] int b = 4; } } Why is [1] allowed, but not [2]?
Re: this(T...) not called in struct constructor
On Wed, Sep 18, 2013 at 10:12:04AM +0200, monarch_dodra wrote: > On Wednesday, 18 September 2013 at 05:28:41 UTC, Timothee Cour > wrote: > >This may have been discussed before, but I'm not sure whether this is > >a bug or not. In any case it's a bit confusing. > > > >struct Foo2{ > > this(T...)(T args){ > >assert(0); > > } > >} > > > >void main(){ > > auto a2=Foo2();//doesn't call assert(0) (ie this(T...) not > >called) > >} > > There is no "argument-less constructor" in D. "Struct()" is just > shorthand for "Struct.init" (bar a few exceptional exceptions: > @disabled this() and static opCall). > > AFAIK, D decided to not have "default" constructors, [...] Note that this only applies to structs. Classes have default ctors. T -- Programming is not just an act of telling a computer what to do: it is also an act of telling other programmers what you wished the computer to do. Both are important, and the latter deserves care. -- Andrew Morton
Re: I cannot understand problem with argument of the function
On Wednesday, 18 September 2013 at 10:37:29 UTC, mrd wrote: Is the contract does not uses its own version of arguments? What is the point of passing earlier changed arguments into contract block? That's a good question. I'll raise it on the main boards.
Re: License of RosettaCode examples (for bearophile:-)
On 18/09/13 11:55, Joseph Rushton Wakeling wrote: On 17/09/13 16:27, bearophile wrote: Joseph Rushton Wakeling: Well, I guess the best thing would be just to write here, "I license the code under the terms of the Boost license" or something similar (public domain is in some ways less good because not every jurisdiction recognizes it, but as far as I'm concerned it's fine too). I'm just looking for something that I can reference to say the code is used under these terms. I license the D program "Queue/Usage" (Faster Version) of the RosettaCode site under the terms of the Boost license. It implements in D2 a simple Circlular Queue able to grow geometrically. The code is visible in this page: http://rosettacode.org/wiki/Queue/Usage#Faster_Version Thank you very much. I really appreciate this. I've added a Ddoc comment to the Dgraph codebase to reflect the origins of the code and your kind license grant: https://github.com/WebDrake/Dgraph/commit/315286b9717e3d078029d77d0972800cbbd7dc42 Let me know if there's anything about that you'd like tweaked. I can also offer a link to your homepage, for example :-)
Re: I cannot understand problem with argument of the function
On Wednesday, 18 September 2013 at 09:56:26 UTC, monarch_dodra wrote: On Wednesday, 18 September 2013 at 09:09:29 UTC, mrd wrote: On Wednesday, 18 September 2013 at 09:07:09 UTC, mrd wrote: Looks like data corruption. Can't help you much without a full piece of code that *reproduces* the issue (reducing it helps too). I will try to do it later. (I tried to copy these functions in a separate file - the problem is not reproduced.) this file: http://pastebin.com/MCm5Yu7K I had to write "isMsbSet" myself. Omg, I am send wrong version of the file! Sorry! Here is it: http://pastebin.com/h950BTyN Your out contracts also fail, because the body of your function modifies "value", but then, you use it in your contract. Is the contract does not uses its own version of arguments? What is the point of passing earlier changed arguments into contract block? I had to change the body to use a copy of the passed in arguments, to verify them. From there, it *still* fails, because your unpackVarint is wrong. You store the result in a size_t, which immediatly overflows. The irony is you put a comment that says "big sized type used also for overflow checking". Why not use a T, or result directly? Even, then, a problem remains that "data[i] & 0b_0111_" is of type int, causing overflow and sign mismatch for anything larger than int.max Above that I'll think later, thanks! (It's amazing that this code passed all higher-level unit tests for several months.)
Re: I cannot understand problem with argument of the function
On Wednesday, 18 September 2013 at 09:09:29 UTC, mrd wrote: On Wednesday, 18 September 2013 at 09:07:09 UTC, mrd wrote: Looks like data corruption. Can't help you much without a full piece of code that *reproduces* the issue (reducing it helps too). I will try to do it later. (I tried to copy these functions in a separate file - the problem is not reproduced.) this file: http://pastebin.com/MCm5Yu7K I had to write "isMsbSet" myself. Also, you "main" doesn't compile: // for( long i = -100; i < 100; i++ ) packVarint( i ); // since "pack" only accepts unsigned. After changing it to packVariant!ulong, it compiles. But it *could* explain the "weird" values you are seeing: -100 => 18446744073709551516. I was wrong about the mask thing, that was just my windows calculator playing tricks on me. Your out contracts also fail, because the body of your function modifies "value", but then, you use it in your contract. I had to change the body to use a copy of the passed in arguments, to verify them. From there, it *still* fails, because your unpackVarint is wrong. You store the result in a size_t, which immediatly overflows. The irony is you put a comment that says "big sized type used also for overflow checking". Why not use a T, or result directly? Even, then, a problem remains that "data[i] & 0b_0111_" is of type int, causing overflow and sign mismatch for anything larger than int.max
Re: License of RosettaCode examples (for bearophile:-)
On 17/09/13 16:27, bearophile wrote: Joseph Rushton Wakeling: Well, I guess the best thing would be just to write here, "I license the code under the terms of the Boost license" or something similar (public domain is in some ways less good because not every jurisdiction recognizes it, but as far as I'm concerned it's fine too). I'm just looking for something that I can reference to say the code is used under these terms. I license the D program "Queue/Usage" (Faster Version) of the RosettaCode site under the terms of the Boost license. It implements in D2 a simple Circlular Queue able to grow geometrically. The code is visible in this page: http://rosettacode.org/wiki/Queue/Usage#Faster_Version Thank you very much. I really appreciate this. If you could add such a notice to the copy on your own site and on RosettaCode it would be even better Nearly all Rosettacode site entries (and all D entries) lack a license notice. It's just bad noise added. For questions ask to Mike in the #rosettacode IRC channel. Ahh, I think I misunderstood some of the RosettaCode documentation which had something along the lines of "Unless the code comes with a different license attached ..." According to their Copyright page, it's advised to place license notices on your RosettaCode user page if you want to use something apart from the GNU FDL: http://rosettacode.org/wiki/Rosetta_Code:Copyrights#Contributors
Re: I cannot understand problem with argument of the function
On Wednesday, 18 September 2013 at 09:09:29 UTC, mrd wrote: On Wednesday, 18 September 2013 at 09:07:09 UTC, mrd wrote: Looks like data corruption. I can not imagine what corruption was going on here: the fact that is contract gets the correct value, but the function itself - not. But they both should use same value source, yep? Can't help you much without a full piece of code that *reproduces* the issue (reducing it helps too).
Re: I cannot understand problem with argument of the function
On Wednesday, 18 September 2013 at 09:07:09 UTC, mrd wrote: Looks like data corruption. Can't help you much without a full piece of code that *reproduces* the issue (reducing it helps too). I will try to do it later. (I tried to copy these functions in a separate file - the problem is not reproduced.) this file: http://pastebin.com/MCm5Yu7K
Re: I cannot understand problem with argument of the function
On Wednesday, 18 September 2013 at 08:25:02 UTC, monarch_dodra wrote: On Wednesday, 18 September 2013 at 04:17:41 UTC, mrd wrote: (question is not about function body realisation - body just don't receives right argument value) Looks like data corruption. Can't help you much without a full piece of code that *reproduces* the issue (reducing it helps too). I will try to do it later. (I tried to copy these functions in a separate file - the problem is not reproduced.) For what it's worth, your "weird" value, it appears to be a bitmask: 18446744073709551615 0x1999 0001_1001 1001_1001 1001_1001 1001_1001 1001_1001 1001_1001 1001_1001 1001_1001 This is usually tell tale invalid memory reads and/or stack corruption. In some other functions of project? TIP: Try marking your function @safe, if possible. Isn't possible because active pointers usage in it
Re: I cannot understand problem with argument of the function
On Wednesday, 18 September 2013 at 04:17:41 UTC, mrd wrote: (question is not about function body realisation - body just don't receives right argument value) Looks like data corruption. Can't help you much without a full piece of code that *reproduces* the issue (reducing it helps too). For what it's worth, your "weird" value, it appears to be a bitmask: 18446744073709551615 0x1999 0001_1001 1001_1001 1001_1001 1001_1001 1001_1001 1001_1001 1001_1001 1001_1001 This is usually tell tale invalid memory reads and/or stack corruption. TIP: Try marking your function @safe, if possible. It will limit the amount of unsafe things you can do, or at least, point you to the unsafe things that could be the source of the problem.
Re: this(T...) not called in struct constructor
On Wednesday, 18 September 2013 at 05:28:41 UTC, Timothee Cour wrote: This may have been discussed before, but I'm not sure whether this is a bug or not. In any case it's a bit confusing. struct Foo2{ this(T...)(T args){ assert(0); } } void main(){ auto a2=Foo2();//doesn't call assert(0) (ie this(T...) not called) } There is no "argument-less constructor" in D. "Struct()" is just shorthand for "Struct.init" (bar a few exceptional exceptions: @disabled this() and static opCall). AFAIK, D decided to not have "default" constructors, as it goes against a few other features (compile time known init state, compile time statics). However, not having a constructor which has "0 arguments" is a gratuitous historical limitation. Chances are it won't change any time soon (or ever). Workarounds include: // // Calling "__ctor" explicitly: Foo2 foo2; foo2.__ctor(); (IMO god awful solution) // // Using static opCall instead of constructor: struct Foo2 { Foo2 static opCall(T...)(T args) { Foo2 ret; //Do something. return ret; } } Foo2 foo2 = Foo2(); //Calls opCall A bit hackish, but works. Unfortunately, this is not a "construction" sequence, so you won't be able to use it with emplace, for example. // // A non-member free function. Similar to static opCall, but a bit less hackish. Just create a free function (usually named the same as your struct, but lowercased). This is also used a lot in Phobos, as it can prevent direct use of the struct: private struct Foo2Result { } public auto foo2(T...)(T args) { Foo2 ret; //Do something. return ret; } auto myFoo2 = foo2(); //Calls the function.
Re: this(T...) not called in struct constructor
On Wednesday, 18 September 2013 at 05:28:41 UTC, Timothee Cour wrote: This may have been discussed before, but I'm not sure whether this is a bug or not. In any case it's a bit confusing. struct Foo2{ this(T...)(T args){ assert(0); } } void main(){ auto a2=Foo2();//doesn't call assert(0) (ie this(T...) not called) } You are not passing a value to the constructor. Use auto a2=Foo2(1);
using scons on 64-bit platform, with gdc
Hi, Not sure it is a bug or a misuse of scons, but on Saucy 64, with scons --version script: v2.3.0, 2013/03/03 09:48:35, by garyo on reepicheep engine: v2.3.0, 2013/03/03 09:48:35, by garyo on reepicheep and a simple SConstruct like: import os env = Environment(ENV = os.environ) env.Program(target='test01', source=Split('test01.d')); it tries to execute: scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... gcc -o test01 -m32 test01.o -L/usr/lib -lphobos2 -lpthread -lm /usr/bin/ld: cannot find -lphobos2 collect2: error: ld returned 1 exit status scons: *** [test01] Error 1 scons: building terminated because of errors. which is expected to fail since: 1) the architecture (and the libraries) are m64, not m32 (why does scons believe that?) 2) the gdc's phobos libraries is called libgphobos2, not libphobos2 Manually correcting and executing the offending line: gcc -o test01 -m64 test01.o -L/usr/lib -lgphobos2 -lpthread -lm works as expected.