Re: how to debug exceptions/asserts thrown in module constructors?
On Monday, 28 November 2016 at 02:52:02 UTC, Basile B. wrote: On Sunday, 27 November 2016 at 22:19:26 UTC, Timothee Cour wrote: Adding ``` b _d_throwc #does nothing ``` Don't ask me why I wouldn't be able to answer. The only thing that I can say is that it's probably related to one of the big change of the year in DMD, i.e C++ interfacing, that led W.Bright to change some stuff to EH.
Re: how to debug exceptions/asserts thrown in module constructors?
On Sunday, 27 November 2016 at 22:19:26 UTC, Timothee Cour wrote: Adding ``` b _d_throwc #does nothing ``` Try instead "b _d_throwdwarf". Changes made earlier this year to EH made _d_throwc obsolete. The equivalent is now _d_throwdwarf. Don't ask me why I wouldn't be able to answer.
Re: Using the result of a comma expression is deprecated
On Sunday, 27 November 2016 at 16:32:26 UTC, Suliman wrote: Looks like you forgot a call to format before the opening parenthesis. should be: string sqlinsert = format(`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); So all string substitute must be called with `format`? Yes, except when you are passing the strings to a function that does it for you, such as the write family. The language doesn't replace "%s" with strings, the format function does. because what ends up happening is : string sqlinsert = data; which is almost certainly not what you want. I thought it's possible to write: string data = "foo" string sqlinsert = data or am I wrong? No, you are not wrong. That is perfectly valid, but that's not what he meant. Your declaration of sqlinsert was made in such a way that you used several commas to separate different values, the last of which was data. The way the comma operator works, that means sqlinsert would be set to data and all the rest ignored. Consider this: void main() { import std.stdio; string s = ("foo %s","bar"); writeln(s); } This prints "bar" and "foo %s" is ignored. That's how the comma operator works outside of a function parameter list. It's also why you got the deprecation message, as this usage will eventually become illegal.
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 23:25:57 UTC, Nicholas Wilson wrote: `_D10neo4jTypes17neo4j_map_entry_t6__initZ`, or Unions are supposed to be default initialised with the first member, a ulong and thus should be zero initialised. Right, but neo4j_map_entry_t is a struct and that's the one it is complaining about.
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 13:54:54 UTC, Adam D. Ruppe wrote: On Sunday, 27 November 2016 at 12:59:32 UTC, Timoses wrote: [...] It is a linker problem because you didn't link to it... D structs have an initializer, even if they are used for interfacing with C. This is a small blob of data called something like `_D10neo4jTypes17neo4j_map_entry_t6__initZ`, or can be all zeroes, and is generated with the interface module. [...] Unions are supposed to be default initialised with the first member, a ulong and thus should be zero initialised. You can often bypass the initializer by using `=0` or `=void` in definitions, but not here... and that is arguably a bug, if you `=void` all fields, it should be free to zero initialize the whole thing, but it doesn't. [...]
Re: how to debug exceptions/asserts thrown in module constructors?
UPDATE: * b Loader.d:123 didn't help either: error: parsing line table prologue at 0x (parsing ended around 0x Breakpoint 1: where = mybinary.temp`D4gtkc6Loader6Linker12_staticDtor3FZv, address = 0x000100315410 (process exited despite breakpoint); dmd's dwarf debug info seems incorrect * b _d_throwc #does nothing * b _d_print_throwable: doesn't show useful context (only shows backtrace after stack unwinding) (lldb) bt * thread #1: tid = 0x6187c1, 0x000100191c30 mybinary.temp _d_print_throwable, stop reason = breakpoint 4.1 * frame #0: 0x000100191c30 mybinary.temp _d_print_throwable frame #1: 0x000100191530 mybinary.temp rt_init + 160 frame #2: 0x000100191a9a mybinary.temp D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 14 frame #3: 0x000100191a40 mybinary.temp D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 36 frame #4: 0x0001001919a6 mybinary.temp _d_run_main + 498 frame #5: 0x00011efa mybinary.temp main + 34 frame #6: 0x7fff89ad65ad libdyld.dylib start + 1 * b _D4gtkc6Loader6Linker11loadLibraryFAyaZv isn't very helpful since this function is complex (and could be inlined more generally) and that function is called many times before the exception is thrown ``` public static void loadLibrary(string library) { void* handle = pLoadLibrary(library); //TODO: A more general way to try more than one version. if ( handle is null && library == importLibs[LIBRARY.GSV] ) handle = pLoadLibrary(importLibs[LIBRARY.GSV1]); if ( handle is null ) throw new Exception("Library load failed: " ~ library); loadedLibraries[library] = handle; } ``` but at least we get a better context: (lldb) bt * thread #1: tid = 0x6187c1, 0x000100315878 mybinary.temp D4gtkc6Loader6Linker11loadLibraryFAyaZv, stop reason = breakpoint 3.1 * frame #0: 0x000100315878 mybinary.temp D4gtkc6Loader6Linker11loadLibraryFAyaZv frame #1: 0x000100315699 mybinary.temp D4gtkc6Loader6Linker9getSymbolFAyaAAyaXPv + 237 frame #2: 0x0001003155a4 mybinary.temp D4gtkc6Loader6Linker9getSymbolFAyaAE4gtkc5paths7LIBRARYXPv + 232 frame #3: 0x0001003163bd mybinary.temp D4gtkc6Loader6Linker39__T4linkTPUZE4gtkc12gobjecttypes5GTypeZ4linkFKPUZE4gtkc12gobjecttypes5GTypeAyaAE4gtkc5paths7LIBRARYXv + 69 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/Loader.d:46 frame #4: 0x00010038c75d mybinary.temp D4gtkc3atk18_sharedStaticCtor4FZv + 77 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/atk.d:36 frame #5: 0x00010038c67d mybinary.temp _D4gtkc3atk15__modsharedctorFZv + 9 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/atk.d:32 frame #6: 0x000100199c17 mybinary.temp D2rt5minfo67__T14runModuleFuncsS442rt5minfo11ModuleGroup8runCtorsMFZ9__lambda2Z14runModuleFuncsMFAxPyS6object10ModuleInfoZv + 91 frame #7: 0x000100199785 mybinary.temp D2rt5minfo11ModuleGroup8runCtorsMFZv + 37 frame #8: 0x000100199a91 mybinary.temp D2rt5minfo13rt_moduleCtorUZ14__foreachbody1MFKS2rt19sections_osx_x86_6412SectionGroupZi + 45 frame #9: 0x000100199a60 mybinary.temp rt_moduleCtor + 20 frame #10: 0x0001001914f3 mybinary.temp rt_init + 99 frame #11: 0x000100191a9a mybinary.temp D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 14 frame #12: 0x000100191a40 mybinary.temp D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 36 frame #13: 0x0001001919a6 mybinary.temp _d_run_main + 498 frame #14: 0x00011efa mybinary.temp main + 34 frame #15: 0x7fff89ad65ad libdyld.dylib start + 1 Ideally there should be a way (via a runtime or compile time option) to wrap the exception throwing (during rt_moduleCtor) inside a extern(C) function that we can put a breakpoint on (and possibly even call backtrace_symbols on) to reproduce: main.d: import ggplotd.gtk; void main(){ } dub.json: { "targetType": "executable", "sourcePaths":["."], "dependencies": { "ggplotd": ">=1.1.0", }, "subConfigurations": { "ggplotd": "ggplotd-gtk", }, "buildRequirements": ["allowWarnings"], }
Re: how to debug exceptions/asserts thrown in module constructors?
UPDATE: * b Loader.d:123 didn't help either: error: parsing line table prologue at 0x (parsing ended around 0x Breakpoint 1: where = mybinary.temp`D4gtkc6Loader6Linker12_staticDtor3FZv, address = 0x000100315410 (process exited despite breakpoint); dmd's dwarf debug info seems incorrect * b _d_throwc #does nothing * b _d_print_throwable: doesn't show useful context (only shows backtrace after stack unwinding) (lldb) bt * thread #1: tid = 0x6187c1, 0x000100191c30 mybinary.temp _d_print_throwable, stop reason = breakpoint 4.1 * frame #0: 0x000100191c30 mybinary.temp _d_print_throwable frame #1: 0x000100191530 mybinary.temp rt_init + 160 frame #2: 0x000100191a9a mybinary.temp D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 14 frame #3: 0x000100191a40 mybinary.temp D2rt6dmain211_d_run_ mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 36 frame #4: 0x0001001919a6 mybinary.temp _d_run_main + 498 frame #5: 0x00011efa mybinary.temp main + 34 frame #6: 0x7fff89ad65ad libdyld.dylib start + 1 * b _D4gtkc6Loader6Linker11loadLibraryFAyaZv isn't very helpful since this function is complex (and could be inlined more generally) and that function is called many times before the exception is thrown ``` public static void loadLibrary(string library) { void* handle = pLoadLibrary(library); //TODO: A more general way to try more than one version. if ( handle is null && library == importLibs[LIBRARY.GSV] ) handle = pLoadLibrary(importLibs[LIBRARY.GSV1]); if ( handle is null ) throw new Exception("Library load failed: " ~ library); loadedLibraries[library] = handle; } ``` but at least we get a better context: (lldb) bt * thread #1: tid = 0x6187c1, 0x000100315878 mybinary.temp D4gtkc6Loader6Linker11loadLibraryFAyaZv, stop reason = breakpoint 3.1 * frame #0: 0x000100315878 mybinary.temp D4gtkc6Loader6Linker11loadLibraryFAyaZv frame #1: 0x000100315699 mybinary.temp D4gtkc6Loader6Linker9getSymbolFAyaAAyaXPv + 237 frame #2: 0x0001003155a4 mybinary.temp D4gtkc6Loader6Linker9getSymbolFAyaAE4gtkc5paths7LIBRARYXPv + 232 frame #3: 0x0001003163bd mybinary.temp D4gtkc6Loader6Linker39__ T4linkTPUZE4gtkc12gobjecttypes5GTypeZ4linkFKPUZE4gtkc12gobje cttypes5GTypeAyaAE4gtkc5paths7LIBRARYXv + 69 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/Loader.d:46 frame #4: 0x00010038c75d mybinary.temp D4gtkc3atk18_sharedStaticCtor4FZv + 77 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/atk.d:36 frame #5: 0x00010038c67d mybinary.temp _D4gtkc3atk15__modsharedctorFZv + 9 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/atk.d:32 frame #6: 0x000100199c17 mybinary.temp D2rt5minfo67__ T14runModuleFuncsS442rt5minfo11ModuleGroup8runCtorsMFZ9__ lambda2Z14runModuleFuncsMFAxPyS6object10ModuleInfoZv + 91 frame #7: 0x000100199785 mybinary.temp D2rt5minfo11ModuleGroup8runCtorsMFZv + 37 frame #8: 0x000100199a91 mybinary.temp D2rt5minfo13rt_moduleCtorUZ14__foreachbody1MFKS2rt19sections_osx_x86_6412SectionGroupZi + 45 frame #9: 0x000100199a60 mybinary.temp rt_moduleCtor + 20 frame #10: 0x0001001914f3 mybinary.temp rt_init + 99 frame #11: 0x000100191a9a mybinary.temp D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 14 frame #12: 0x000100191a40 mybinary.temp D2rt6dmain211_d_run_ mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 36 frame #13: 0x0001001919a6 mybinary.temp _d_run_main + 498 frame #14: 0x00011efa mybinary.temp main + 34 frame #15: 0x7fff89ad65ad libdyld.dylib start + 1 Ideally there should be a way (via a runtime or compile time option) to wrap the exception throwing (during rt_moduleCtor) inside a extern(C) function that we can put a breakpoint on (and possibly even call backtrace_symbols on) On Sun, Nov 27, 2016 at 2:19 PM, Timothee Courwrote: > in the process of trying to debug https://github.com/ > BlackEdder/ggplotd/issues/32 I would like to get a stracktrace and/or put > a breakpoint before exception is thrown: > > > ``` > lldb $binary > r > (lldb) > Process 34168 resuming > object.Exception@../../../../.dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/Loader.d(123): > Library load failed: libatk-1.0.dylib > Process 34168 exited with status = 1 (0x0001) > ``` > > Adding > ``` > b _d_throwc #does nothing > ``` > > didn't help, also, it hasn't entered d main yet so `Runtime.traceHandler = > ` isn't helpful. > > The fix here was to lookup the code, find the corresponding mangled name > location and add a breakpoint via `b _D4gtkc6Loader6Linker11loadLibraryFAyaZv` > but is there a general fix? > >
Re: non-constant expression ["foo":5, "bar":10, "baz":2000]
On Saturday, 26 November 2016 at 17:37:57 UTC, Paolo Invernizzi wrote: This is stated in documentation [1]: immutable long[string] aa = [ "foo": 5, "bar": 10, "baz": 2000 ]; unittest { assert(aa["foo"] == 5); assert(aa["bar"] == 10); assert(aa["baz"] == 2000); } But results to: Error: non-constant expression ["foo":5L, "bar":10L, "baz":2000L] Known bug? If yes, Is there the need to emend the documentation, till the bug is open? --- /Paolo Known bug. If you need a workaround, initialising the variable at load-time with `static this` should help in some cases.
how to debug exceptions/asserts thrown in module constructors?
in the process of trying to debug https://github.com/BlackEdder/ggplotd/issues/32 I would like to get a stracktrace and/or put a breakpoint before exception is thrown: ``` lldb $binary r (lldb) Process 34168 resuming object.Exception@../../../../.dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/Loader.d(123): Library load failed: libatk-1.0.dylib Process 34168 exited with status = 1 (0x0001) ``` Adding ``` b _d_throwc #does nothing ``` didn't help, also, it hasn't entered d main yet so `Runtime.traceHandler = ` isn't helpful. The fix here was to lookup the code, find the corresponding mangled name location and add a breakpoint via `b _D4gtkc6Loader6Linker11loadLibraryFAyaZv` but is there a general fix?
Re: Parsing a string to instantiate classes at runtime
On 11/27/2016 10:19 PM, Marduk wrote: On Sunday, 27 November 2016 at 21:10:30 UTC, ag0aep6g wrote: Can you link that post, please? I can't imagine what "dynamic mixin" could refer to. Sure, it's here: http://forum.dlang.org/post/xmnnsdiuwyjrhkasy...@forum.dlang.org Ok, that's a hypothetical. It's "if D had a 'dynamic mixin', then we could do fancy things with it." D doesn't have a 'dynamic mixin', so you can't do those fancy things, at least not in the envisioned way.
Re: non-constant expression ["foo":5, "bar":10, "baz":2000]
On Saturday, 26 November 2016 at 19:57:21 UTC, Adam D. Ruppe wrote: On Saturday, 26 November 2016 at 17:37:57 UTC, Paolo Invernizzi wrote: This is stated in documentation [1]: What's the link? This is a known limitation, it has never worked. The docs should reflect that, though some day, it might start working. Sorry, I forgot to past it in the previous post: here it is. https://dlang.org/spec/hash-map.html#static_initialization -- Paolo
Re: Parsing a string to instantiate classes at runtime
On Sunday, 27 November 2016 at 21:10:30 UTC, ag0aep6g wrote: Can you link that post, please? I can't imagine what "dynamic mixin" could refer to. Sure, it's here: http://forum.dlang.org/post/xmnnsdiuwyjrhkasy...@forum.dlang.org In that thread they also mention Object.factory, but the documentation says that the class must have either no constructor or the default constructor, which is not my case.
Re: Parsing a string to instantiate classes at runtime
On 11/27/2016 10:02 PM, Marduk wrote: I read in an old post in these forums that with a dynamic mixin it is possible to add structures and classes at runtime. I searched "dynamic mixin" but I did not find more information. Can you link that post, please? I can't imagine what "dynamic mixin" could refer to.
Re: Instantiating a class with different types at runtime
On 11/27/2016 09:52 PM, Marduk wrote: class Example { this(Type_left x, Type_right y) { this.left = x; this.right = y; } Type_left left; Type_right right; } Such that at runtime I can instantiate it with different types: new Example(int a, int b); new Example(int a, string b); Turn Example into a template, and add a free function for nice construction: class Example(Type_left, Type_right) { /* ... as you had it ... */ } Example!(L, R) makeExample(L, R)(L x, R y) { return new Example!(L, R)(x, y); } void main() { auto foo = makeExample(1, 2); auto bar = makeExample(3, "baz"); } Note that Example is not a type, but a template. That means, foo and bar have different types, because their types are different instantiations of the Example template. You can define a common interface or (possibly abstract) base class.
Parsing a string to instantiate classes at runtime
Dear all, I would like to write a program that: 1. Receives a string from the UI 2. Parses the string 3. Instantiates classes, whose names are contained in the string, passing parts of the string as constructor arguments. From my experience with other programming languages, I suppose I need to define an eval function. I read in an old post in these forums that with a dynamic mixin it is possible to add structures and classes at runtime. I searched "dynamic mixin" but I did not find more information. Any help will be greatly appreciated.
Re: Instantiating a class with different types at runtime
On Sunday, 27 November 2016 at 20:52:06 UTC, Marduk wrote: Dear all, I would like to have a kind of template class like the following: class Example { this(Type_left x, Type_right y) { this.left = x; this.right = y; } Type_left left; Type_right right; } Such that at runtime I can instantiate it with different types: new Example(int a, int b); new Example(int a, string b); I have read about templates and abstract classes, but I have not figured how to get this to work. Thanks. class Example(L, R) { L _left; R _right; this(L l, R r) { _left = l; _right = r; } }
Instantiating a class with different types at runtime
Dear all, I would like to have a kind of template class like the following: class Example { this(Type_left x, Type_right y) { this.left = x; this.right = y; } Type_left left; Type_right right; } Such that at runtime I can instantiate it with different types: new Example(int a, int b); new Example(int a, string b); I have read about templates and abstract classes, but I have not figured how to get this to work. Thanks.
Re: Using the result of a comma expression is deprecated
On Sunday, 27 November 2016 at 16:42:17 UTC, Suliman wrote: Am I right understand that `scope(exit)` should be always at top, otherwise it would not work (it's very strange because by the docs it's calling every time when function out of the scopes)? No, scope(exit) queues the thing for execution, so it doesn't necessarily need to be at the top. void test() { scope(exit) writeln("1"); writeln("2"); scope(exit) writeln("3"); } That would print "2, 3, 1". The first line queues 1. The second line runs immediately and prints 2. The third line queues 3. When the function returns, all queued things are played back in reverse order. Thus, 3 goes first, then 1. If you returned right after the second line, you would only see "2, 1", since the queuing of the 3 would never happen.
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 15:56:13 UTC, Stefan Koch wrote: Does your answer also explain why it works when I move the mytypes.d into the source/ folder? dub will link it in when it is in the source folder. exactly.
std.net.curl application throws an exception
try to compile this program from std.net.curl import std.net.curl, std.stdio; void main() { auto range1 = byLineAsync("www.google.com"); auto range2 = byLineAsync("www.wikipedia.org"); foreach (line; byLineAsync("dlang.org")) writeln(line); foreach (line; range1) writeln(line); foreach (line; range2) writeln(line); } I compile this program like this. $ dmd internet.d -ofinternet or dmd -I/usr/include/dmd/phobos -L-l:libcurl.so.4.2.0 internet.d -ofinternet The program compiles fine but it throws an exception. std.concurrency.PriorityMessageException@std/concurrency.d(273): Priority message ??:? _D3std11concurrency10MessageBox160__T3getTDFS3std11concurrency3TidS3std3net4curl21__T11CurlMessageTAyaZ11CurlMessageZbTDFS3std11concurrency3TidS3std3net4curl19__T11CurlMessageTbZ11CurlMessageZbZ3getMFDFS3std11concurrency3TidS3std3net4curl21__T11CurlMessageTAyaZ11CurlMessageZbDFS3std11concurrency3TidS3std3net4curl19__T11CurlMessageTbZ11CurlMessageZbZ3ptyMFKS3std11concurrency36__T4ListTS3std11concurrency7MessageZ4ListZb [0x81d03f4] ??:? bool std.concurrency.MessageBox.get!(bool delegate(std.concurrency.Tid, std.net.curl.CurlMessage!(immutable(char)[]).CurlMessage), bool delegate(std.concurrency.Tid, std.net.curl.CurlMessage!(bool).CurlMessage)).get(bool delegate(std.concurrency.Tid, std.net.curl.CurlMessage!(immutable(char)[]).CurlMessage), bool delegate(std.concurrency.Tid, std.net.curl.CurlMessage!(bool).CurlMessage)) [0x81cfeed] ??:? void std.concurrency.receive!(bool delegate(std.concurrency.Tid, std.net.curl.CurlMessage!(immutable(char)[]).CurlMessage), bool delegate(std.concurrency.Tid, std.net.curl.CurlMessage!(bool).CurlMessage)).receive(bool delegate(std.concurrency.Tid, std.net.curl.CurlMessage!(immutable(char)[]).CurlMessage), bool delegate(std.concurrency.Tid, std.net.curl.CurlMessage!(bool).CurlMessage)) [0x81cfd08] ??:? void std.net.curl.AsyncLineInputRange!(char).AsyncLineInputRange.__mixin5.tryEnsureUnits() [0x81ccb87] ??:? @property bool std.net.curl.AsyncLineInputRange!(char).AsyncLineInputRange.__mixin5.empty() [0x81cc7db] ??:? _Dmain [0x81b47b8] ??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x81d9292] ??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x81d91dc] ??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x81d924e] ??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x81d91dc] ??:? _d_run_main [0x81d916e] ??:? main [0x81d3393] ??:? __libc_start_main [0x129532] I use dmd v2.072.0
Re: Using the result of a comma expression is deprecated
As an aside, for security reasons you should use a prepared statement. Even if it's server-side code and there is no any iteration with user data (they come as JSON) Also, this is a decent usecase for scope(exit) but it should be put earlier in the function. Am I right understand that `scope(exit)` should be always at top, otherwise it would not work (it's very strange because by the docs it's calling every time when function out of the scopes)?
Re: Using the result of a comma expression is deprecated
Looks like you forgot a call to format before the opening parenthesis. should be: string sqlinsert = format(`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); because what ends up happening is : string sqlinsert = data; which is almost certainly not what you want. So all string substitute must be called with `format`? because what ends up happening is : string sqlinsert = data; which is almost certainly not what you want. I thought it's possible to write: string data = "foo" string sqlinsert = data or am I wrong?
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 15:23:33 UTC, Timoses wrote: On Sunday, 27 November 2016 at 14:27:54 UTC, Adam D. Ruppe wrote: That's because int is zero initialized by default and thus doesn't need anything more than a call to zero memory function, and double isn't (it is NaN), so it gets an initializer data blob. If you make it = 0 it might work, but even then, the compiler may want to reference the initializer just because there's a non-default init value! Does your answer also explain why it works when I move the mytypes.d into the source/ folder? dub will link it in when it is in the source folder.
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 14:27:54 UTC, Adam D. Ruppe wrote: That's because int is zero initialized by default and thus doesn't need anything more than a call to zero memory function, and double isn't (it is NaN), so it gets an initializer data blob. If you make it = 0 it might work, but even then, the compiler may want to reference the initializer just because there's a non-default init value! Does your answer also explain why it works when I move the mytypes.d into the source/ folder?
Re: A simplification of the RvalueRef idiom
On Friday, 25 November 2016 at 17:21:52 UTC, Nick Treleaven wrote: I've started documenting it now, will post a PR soon. https://github.com/dlang/dlang.org/pull/1519
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 14:12:31 UTC, Timoses wrote: If I change the union's variable type to "int" (or any other) it compiles just fine. So the problem seems to be the "double" value. That's because int is zero initialized by default and thus doesn't need anything more than a call to zero memory function, and double isn't (it is NaN), so it gets an initializer data blob. If you make it = 0 it might work, but even then, the compiler may want to reference the initializer just because there's a non-default init value! Should I still report it as a bug here: It isn't a bug, this is working as designed [1]. Making it skip the initializer with =void or =0 explicit init values is a valid enhancement request though. 1: search for "default" on this page http://dlang.org/spec/struct.html#static_struct_init
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 13:22:36 UTC, Nicholas Wilson wrote: The missing symbol is the struct initialiser for neo4j_map_entry_t. Not sure why is not being generated (it should), possibly because of the union. That seems like a bug please report it. http://issues.dlang.org/ Thanks for the answer, Nicholas! I've created a small example: source/app.d import mytypes; void main() { myunion[2] t; } include/mytypes.d: module mytypes; union myunion { double b; }; dub.json: "importPaths": ["include"] Output: _ dmd -c -of.dub/build/application-debug-posix.osx-x86_64-dmd_2072-99D5F2E2DCAF9FF19FE5AE403C120D52/testomat.o -debug -g -w -version=Have_testomat -Iinclude source/app.d -vcolumns Linking... dmd -of.dub/build/application-debug-posix.osx-x86_64-dmd_2072-99D5F2E2DCAF9FF19FE5AE403C120D52/testomat .dub/build/application-debug-posix.osx-x86_64-dmd_2072-99D5F2E2DCAF9FF19FE5AE403C120D52/testomat.o -g Undefined symbols for architecture x86_64: "_D7mytypes7myunion6__initZ", referenced from: __Dmain in testomat.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: linker exited with status 1 FAIL .dub/build/application-debug-posix.osx-x86_64-dmd_2072-99D5F2E2DCAF9FF19FE5AE403C120D52/ testomat executable dmd failed with exit code 1. _ If I change the union's variable type to "int" (or any other) it compiles just fine. So the problem seems to be the "double" value. It also compiles just fine when I move "mytypes.d" into the source/ folder (even with "double"!!!). Should I still report it as a bug here: https://issues.dlang.org/ ? Or is it dub related?
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 12:59:32 UTC, Timoses wrote: Why is it a linker problem? I'm not linking to the c interface but merely using D structs... It is a linker problem because you didn't link to it... D structs have an initializer, even if they are used for interfacing with C. This is a small blob of data called something like `_D10neo4jTypes17neo4j_map_entry_t6__initZ`, or can be all zeroes, and is generated with the interface module. So if you use the initializer from the interface module, but do not link it in, you get an undefined symbol. Easiest fix: just link in that .d file and use the automatic features. Why does your struct have an initializer data symbol instead of being all zeroes? I'm not entirely sure, but I think it is because the contents are structs and it didn't look inside those structs to see if they too are zeroes, it just assumed struct = fancy initialized. That's arguably an enhancement request, but I wouldn't call it a bug. You can often bypass the initializer by using `=0` or `=void` in definitions, but not here... and that is arguably a bug, if you `=void` all fields, it should be free to zero initialize the whole thing, but it doesn't. Why do you use the initializer? Look at each of these lines: neo4j_map_entry_t[] mapa2; // yes neo4j_map_entry_t entry1 = { key: neo4j_string("prop1"), value: neo4j_string("testprop1")}; // yes neo4j_map_entry_t entry2 = { key: neo4j_string("prop2"), value: neo4j_string("testprop2")}; // yes neo4j_map_entry_t* mapp; // yes Those work because nothing is default initialized: pointers and arrays start as null (and thus point to no actual struct data). The middle lines have you explicitly initializing it, so again, no default needed. // These don't neo4j_map_entry_t[2] mapa1; // no This is basically the same as `neo4j_map_entry_y a;` done twice - you create a struct, which is default initialized, which references that data. You can bypass this with `=void` at the end of that line. mapa2.length = 2; // no This also default initializes the new items you add. Just don't use that length function if you don't want to link in the other .d file. mapa2 ~= entry1; // no I think the implementation does length += 1, then copy arr[$-1] = entry1, so there's a temporary default in there. There's arguably a better implementation possible so this one *could* work. But if it doesn't now, just avoid that function (try something like std.array.uninitializedArray perhaps). neo4j_map_entry_t[] mapa3 = [{ key: neo4j_null, value: neo4j_null}]; // no And I don't know with this one, since I don't know what neo4j_null is. Perhaps you just didn't do the extern symbol right, or perhaps it too is a little data blob that should be linked in. But while this can be annoying, it isn't really a bug - it is D's auto initialize feature creating some data that you didn't link. Avoiding D-specific features and bypassing initialization with =void can skip it, but I recommend just linking in the module.
Re: Creating array of structs being used in C interface
On Sunday, 27 November 2016 at 12:59:32 UTC, Timoses wrote: Hi there, I've got a problem interfacing to a C library. The following structs are used by the library's .d file that I've written. struct neo4j_map_entry_t { neo4j_value_t key; neo4j_value_t value; }; struct neo4j_value_t { uint8_t _vt_off; uint8_t _type; /*TODO: combine with _vt_off? (both always have same value)*/ uint16_t _pad1; uint32_t _pad2; _neo4j_value_data _vdata; }; union _neo4j_value_data { uint64_t _int; uintptr_t _ptr; double _dbl; }; Now I'd also like to use them in my own code. However, I fail at generating an array of map entries: void test() { // These work neo4j_map_entry_t[] mapa2; // yes neo4j_map_entry_t entry1 = { key: neo4j_string("prop1"), value: neo4j_string("testprop1")}; // yes neo4j_map_entry_t entry2 = { key: neo4j_string("prop2"), value: neo4j_string("testprop2")}; // yes neo4j_map_entry_t* mapp; // yes // These don't neo4j_map_entry_t[2] mapa1; // no mapa2.length = 2; // no mapa2 ~= entry1; // no neo4j_map_entry_t[] mapa3 = [{ key: neo4j_null, value: neo4j_null}]; // no } The output is: __ myprogram ~master: building configuration "unittest"... Linking... Undefined symbols for architecture x86_64: "_D10neo4jTypes17neo4j_map_entry_t6__initZ", referenced from: _D6myprogram6myprogram5test2MFZv in myprogram.o ld: symbol(s) not found for architecture x86_64 __ Why is it a linker problem? I'm not linking to the c interface but merely using D structs... The missing symbol is the struct initialiser for neo4j_map_entry_t. Not sure why is not being generated (it should), possibly because of the union. That seems like a bug please report it. http://issues.dlang.org/
Creating array of structs being used in C interface
Hi there, I've got a problem interfacing to a C library. The following structs are used by the library's .d file that I've written. struct neo4j_map_entry_t { neo4j_value_t key; neo4j_value_t value; }; struct neo4j_value_t { uint8_t _vt_off; uint8_t _type; /*TODO: combine with _vt_off? (both always have same value)*/ uint16_t _pad1; uint32_t _pad2; _neo4j_value_data _vdata; }; union _neo4j_value_data { uint64_t _int; uintptr_t _ptr; double _dbl; }; Now I'd also like to use them in my own code. However, I fail at generating an array of map entries: void test() { // These work neo4j_map_entry_t[] mapa2; // yes neo4j_map_entry_t entry1 = { key: neo4j_string("prop1"), value: neo4j_string("testprop1")}; // yes neo4j_map_entry_t entry2 = { key: neo4j_string("prop2"), value: neo4j_string("testprop2")}; // yes neo4j_map_entry_t* mapp; // yes // These don't neo4j_map_entry_t[2] mapa1; // no mapa2.length = 2; // no mapa2 ~= entry1; // no neo4j_map_entry_t[] mapa3 = [{ key: neo4j_null, value: neo4j_null}]; // no } The output is: __ myprogram ~master: building configuration "unittest"... Linking... Undefined symbols for architecture x86_64: "_D10neo4jTypes17neo4j_map_entry_t6__initZ", referenced from: _D6myprogram6myprogram5test2MFZv in myprogram.o ld: symbol(s) not found for architecture x86_64 __ Why is it a linker problem? I'm not linking to the c interface but merely using D structs...
Re: Using the result of a comma expression is deprecated
On Sunday, 27 November 2016 at 12:13:03 UTC, Nicholas Wilson wrote: On Sunday, 27 November 2016 at 11:49:25 UTC, Suliman wrote: On Sunday, 27 November 2016 at 11:21:58 UTC, drug007 wrote: void dbInsert(string login, string uploading_date, string geometry_type, string data) { Statement stmt = conn.createStatement(); string sqlinsert = (`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); stmt.executeUpdate(sqlinsert); scope(exit) stmt.close(); // closing } full code. Looks like you forgot a call to format before the opening parenthesis. should be: string sqlinsert = format(`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); because what ends up happening is : string sqlinsert = data; which is almost certainly not what you want. As an aside, for security reasons you should use a prepared statement. Also, this is a decent usecase for scope(exit) but it should be put earlier in the function.
Re: Using the result of a comma expression is deprecated
On Sunday, 27 November 2016 at 11:49:25 UTC, Suliman wrote: On Sunday, 27 November 2016 at 11:21:58 UTC, drug007 wrote: On 27.11.2016 14:07, Suliman wrote: I am getting deprecation message: "Using the result of a comma expression is deprecated" on this code: string sqlinsert = (`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); What's wrong with it? Didn't you miss something like class/structure/function before "(`INSERT..."? What result do you expect? void dbInsert(string login, string uploading_date, string geometry_type, string data) { Statement stmt = conn.createStatement(); string sqlinsert = (`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); stmt.executeUpdate(sqlinsert); scope(exit) stmt.close(); // closing } full code. Looks like you forgot a call to format before the opening parenthesis. should be: string sqlinsert = format(`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); because what ends up happening is : string sqlinsert = data; which is almost certainly not what you want.
Re: Using the result of a comma expression is deprecated
On Sunday, 27 November 2016 at 11:21:58 UTC, drug007 wrote: On 27.11.2016 14:07, Suliman wrote: I am getting deprecation message: "Using the result of a comma expression is deprecated" on this code: string sqlinsert = (`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); What's wrong with it? Didn't you miss something like class/structure/function before "(`INSERT..."? What result do you expect? void dbInsert(string login, string uploading_date, string geometry_type, string data) { Statement stmt = conn.createStatement(); string sqlinsert = (`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); stmt.executeUpdate(sqlinsert); scope(exit) stmt.close(); // closing } full code.
Re: Using the result of a comma expression is deprecated
On 27.11.2016 14:07, Suliman wrote: I am getting deprecation message: "Using the result of a comma expression is deprecated" on this code: string sqlinsert = (`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); What's wrong with it? Didn't you miss something like class/structure/function before "(`INSERT..."? What result do you expect?
Using the result of a comma expression is deprecated
I am getting deprecation message: "Using the result of a comma expression is deprecated" on this code: string sqlinsert = (`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); What's wrong with it?
Re: Given two AliasSeq (A and B) and template T, how to make AliasSeq!(T!(A[0], B[0]) ... T!(A[n], B[n])) ?
On Sunday, 27 November 2016 at 07:38:53 UTC, Nicholas Wilson wrote: Whoops it would help if I read your question. You want to use Iota in conjunction with staticMap. alias pairs(int N, alias a, alias b) = AliasSeq(a[N],b[N]); alias C = staticMap!(T,staticMap(pairs,Iota!N)); That didn't actually work, but I got it working with: alias pairs(size_t n) = T!(A[n], B[n]); alias C = staticMap!(pairs, Iota!(A.length));