Re: Why is this allowed
On Wednesday, 1 July 2020 at 20:05:51 UTC, tsbockman wrote: If you want the compiler to stop you from accidentally keeping references to stack variables past the end of their scope, you need to annotate your functions @safe and compile with -preview=dip1000: https://run.dlang.io/is/3VdDaN Furthermore, the problem your example shows has nothing to do with implicit static to dynamic array conversion, as without @safe the same error can easily be committed with non-array types: https://run.dlang.io/is/nBjibd Hmm. Those run.dlang.io short links seem to allow editing of the code, so I'd better paste it here for permanence: // Compile with -preview=dip1000 struct Database { int[] data; void set(int[] _data) @safe { data = _data; } } void myFunc(ref Database db) @safe { int[3] x; db.set(x); // This is a compile-time error, as it should be. } Database theDB; void main() { myFunc(theDB); } // This version shows that the problem is not using @safe and dip1000, // not anything to do with arrays: struct Database { int* data; void set(ref int _data) { data = &_data; } } void myFunc(ref Database db) { int x; db.set(x); // oops } Database theDB; void main() { myFunc(theDB); }
Re: Why is this allowed
On Tuesday, 30 June 2020 at 16:36:45 UTC, H. S. Teoh wrote: And on that note, this implicit static -> dynamic array conversion is seriously a nasty misfeature that ought to be killed with fire. It leads to bugs like this: struct Database { int[] data; void set(int[] _data) { data = _data; } } void myFunc(ref Database db) { int[3] x; db.set(x); // oops } If you want the compiler to stop you from accidentally keeping references to stack variables past the end of their scope, you need to annotate your functions @safe and compile with -preview=dip1000: https://run.dlang.io/is/3VdDaN Furthermore, the problem your example shows has nothing to do with implicit static to dynamic array conversion, as without @safe the same error can easily be committed with non-array types: https://run.dlang.io/is/nBjibd
Re: Print only part of a stack trace
On Wednesday, 1 July 2020 at 19:33:08 UTC, JN wrote: Bit off-topic, but if you can use them, debug contexts offer much better OpenGL error-checking experience. https://www.khronos.org/opengl/wiki/Debug_Output . Instead of checking glGetError() after each call, you can setup a C callback that will trigger whenever an error occurs. It also offers some vendor-specific performance warnings. I use those as well, to get a more detailed message about the error than the error code alone. While it helps describing _what_ went wrong, it doesn't tell me _where_ it went wrong. I tried doing assert(0) in the callback, but even with glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS), the stack trace looks something like this: app.d: debugCallback [0x559eda75c7e8] ??:? [0x7f4a0bffa7d7] And then it ends. It seems like it goes up into the OpenGL dll and then gets stuck, it does not trace back to the call site of the glFunction that failed.
Re: Why is this allowed
On Wednesday, 1 July 2020 at 15:57:24 UTC, Nathan S. wrote: On Tuesday, 30 June 2020 at 16:22:57 UTC, JN wrote: Spent some time debugging because I didn't notice it at first, essentially something like this: int[3] foo = [1, 2, 3]; foo = 5; writeln(foo); // 5, 5, 5 Why does such code compile? I don't think this should be permitted, because it's easy to make a mistake (when you wanted foo[index] but forgot the []). If someone wants to assign a value to every element they could do foo[] = 5; instead which is explicit. What's your opinion on using that syntax in the initial declaration, like `float[16] foo = 0`? I don't like it. I'd prefer: float[16] foo = [ 0 ]; or float[16] foo = { 0 }; or float[16] foo(0);
Re: Print only part of a stack trace
On Wednesday, 1 July 2020 at 18:30:15 UTC, Dennis wrote: I have a function that checks a global error constant of a C library (OpenGL) like this: ``` void assertNoOpenGLErrors() { if (glGetError() != GL_NO_ERROR) { assert(0); // stack trace points to here instead of caller } } Bit off-topic, but if you can use them, debug contexts offer much better OpenGL error-checking experience. https://www.khronos.org/opengl/wiki/Debug_Output . Instead of checking glGetError() after each call, you can setup a C callback that will trigger whenever an error occurs. It also offers some vendor-specific performance warnings.
Re: Print only part of a stack trace
On Wednesday, 1 July 2020 at 18:54:55 UTC, Dennis wrote: It sort of works, but it seems it does not start at the right stack frame, the top item is this: ??:? void rt.dmain2._d_run_main2(char[][], ulong, extern (C) int function(char[][])*).runAll().__lambda1() [0x55c19a09c1fa] So dmd skips the first 5 stack frames to account for _d_traceContext, _d_createTrace etc, while ldc filters out by filename. https://github.com/ldc-developers/druntime/blob/cc97ccd00d4082221eee1d5afdbd775201d75877/src/core/runtime.d#L855 I can easily work around this, though it's unfortunate that the public API of DefaultTraceInfo has this limitation.
Re: Print only part of a stack trace
On Wednesday, 1 July 2020 at 18:44:10 UTC, Stanislav Blinov wrote: void assertNoOpenGLErrors(string file = __FILE__, int line = __LINE__, string func = __PRETTY_FUNCTION__) { if (glGetError() != GL_NO_ERROR) { print(file, ":", line, ":", func, ": blah"); exit(); } } :) I love __FILE__ and __LINE__, but in this case they won't cut it. In my actual code there's usually one or two more functions inbetween, and amending hundreds of signatures with __FILE__ and __LINE__ for a little debugging convenience is not worth it. I'm now trying to call the defaultTraceHandler manually like this: ``` void bar() { import std.stdio; import core.runtime: defaultTraceHandler; auto res = defaultTraceHandler(null); writeln(res); } void foo() {bar();} void main() {foo();} ``` It sort of works, but it seems it does not start at the right stack frame, the top item is this: ??:? void rt.dmain2._d_run_main2(char[][], ulong, extern (C) int function(char[][])*).runAll().__lambda1() [0x55c19a09c1fa]
Re: Print only part of a stack trace
On Wednesday, 1 July 2020 at 17:44:45 UTC, Dennis wrote: On assertion failure, the default error handler prints a stack trace that looks like this My cgi.d does something just like that. It just does `exception.toString()` then `splitLines` on that string. Element exceptionToElement(Throwable t) { auto div = Element.make("div"); div.addClass("exception-display"); div.addChild("p", t.msg); div.addChild("p", "Inner code origin: " ~ typeid(t).name ~ "@" ~ t.file ~ ":" ~ to!string(t.line)); auto pre = div.addChild("pre"); string s; s = t.toString(); Element currentBox; bool on = false; foreach(line; s.splitLines) { if(!on && line.startsWith("-")) on = true; if(!on) continue; if(line.indexOf("arsd/") != -1) { if(currentBox is null) { currentBox = pre.addChild("details"); currentBox.addChild("summary", "Framework code"); } currentBox.addChild("span", line ~ "\n"); } else { pre.addChild("span", line ~ "\n"); currentBox = null; } } return div; }
Re: Print only part of a stack trace
On Wednesday, 1 July 2020 at 18:30:15 UTC, Dennis wrote: I have a function that checks a global error constant of a C library (OpenGL) like this: ``` void assertNoOpenGLErrors() { if (glGetError() != GL_NO_ERROR) { assert(0); // stack trace points to here instead of caller } } ``` And I would like to rewrite it to this: ``` void assertNoOpenGLErrors() { if (glGetError() != GL_NO_ERROR) { print(getStackTrace().filterTrace()); exit(); } } ``` void assertNoOpenGLErrors(string file = __FILE__, int line = __LINE__, string func = __PRETTY_FUNCTION__) { if (glGetError() != GL_NO_ERROR) { print(file, ":", line, ":", func, ": blah"); exit(); } } :)
Re: Print only part of a stack trace
On Wednesday, 1 July 2020 at 18:05:09 UTC, Jacob Carlborg wrote: [1] https://dlang.org/phobos/core_runtime.html#.Runtime.traceHandler Thanks, but I don't want to re-implement the default trace handler, I want to use it on a specific location and capture its output. I'll be more specific in what I want to achieve. I have a function that checks a global error constant of a C library (OpenGL) like this: ``` void assertNoOpenGLErrors() { if (glGetError() != GL_NO_ERROR) { assert(0); // stack trace points to here instead of caller } } ``` And I would like to rewrite it to this: ``` void assertNoOpenGLErrors() { if (glGetError() != GL_NO_ERROR) { print(getStackTrace().filterTrace()); exit(); } } ``` So that the stack trace immediately points to the function that raised the OpenGL error, instead of it being buried in a large trace.
Re: Print only part of a stack trace
On 2020-07-01 19:44, Dennis wrote: On assertion failure, the default error handler prints a stack trace that looks like this [library functions] [application functions] [druntime start-up functions] I'm only interested in application functions, the rest is noise. I could easily filter unwanted lines out if I had the stack trace in string form, but I don't know how to obtain that. Is there a simple way to do this, or should I delve into Druntime internals? Could `Runtime.traceHandler` [1] be that you're looking for? [1] https://dlang.org/phobos/core_runtime.html#.Runtime.traceHandler -- /Jacob Carlborg
Print only part of a stack trace
On assertion failure, the default error handler prints a stack trace that looks like this [library functions] [application functions] [druntime start-up functions] I'm only interested in application functions, the rest is noise. I could easily filter unwanted lines out if I had the stack trace in string form, but I don't know how to obtain that. Is there a simple way to do this, or should I delve into Druntime internals?
Re: Why is this allowed
On 7/1/20 11:57 AM, Nathan S. wrote: On Tuesday, 30 June 2020 at 16:22:57 UTC, JN wrote: Spent some time debugging because I didn't notice it at first, essentially something like this: int[3] foo = [1, 2, 3]; foo = 5; writeln(foo); // 5, 5, 5 Why does such code compile? I don't think this should be permitted, because it's easy to make a mistake (when you wanted foo[index] but forgot the []). If someone wants to assign a value to every element they could do foo[] = 5; instead which is explicit. What's your opinion on using that syntax in the initial declaration, like `float[16] foo = 0`? It's important to keep at least something that allows such setting. It would be reasonable to do this with a function as well. Is it possible to have the initialization syntax work differently from the assignment (i.e. allow the initialization as above, but require the brackets for assignment)? -Steve
Re: Why is this allowed
On Tuesday, 30 June 2020 at 16:22:57 UTC, JN wrote: Spent some time debugging because I didn't notice it at first, essentially something like this: int[3] foo = [1, 2, 3]; foo = 5; writeln(foo); // 5, 5, 5 Why does such code compile? I don't think this should be permitted, because it's easy to make a mistake (when you wanted foo[index] but forgot the []). If someone wants to assign a value to every element they could do foo[] = 5; instead which is explicit. What's your opinion on using that syntax in the initial declaration, like `float[16] foo = 0`?
Re: Why is this allowed
On Tuesday, 30 June 2020 at 16:22:57 UTC, JN wrote: Why does such code compile? I don't think this should be permitted, because it's easy to make a mistake (when you wanted foo[index] but forgot the []). If someone wants to assign a value to every element they could do foo[] = 5; instead which is explicit. Totally agree. In most of cases implicit actions lead to errors. Even if they have a specific use case and really convenient.
Re: idiomatic output given -preview=nosharedaccess ,
On Tuesday, 30 June 2020 at 20:43:00 UTC, Bruce Carneal wrote: On Tuesday, 30 June 2020 at 20:12:59 UTC, Stanislav Blinov wrote: On Tuesday, 30 June 2020 at 20:04:33 UTC, Steven Schveighoffer wrote: The answer is -- update Phobos so it works with -nosharedaccess :) Yeah... and dip1000. And dip1008. And dip... :) Didn't want to be snippity but, yeah, with "hello world" breaking I thought it was time to fix the standard library. Thanks for the polite confirmation(s). Looking at the stdio.d source it appears that a cast on one line within a template could give nosharedaccess programs access to stdio, stdout, and stderr. A bug/enhancement request was filed.
Re: How to implement Canceleable spawn() from parent
On 7/1/20 2:41 AM, aberba wrote: On Tuesday, 30 June 2020 at 14:43:40 UTC, Steven Schveighoffer wrote: On 6/30/20 10:15 AM, Simen Kjærås wrote: [...] My thinking is I don't want regular consumers using the package to think about the technicality of thread_joinAll() at all. Thinking about putting it in a mixin like: mixin KeepRunning; Or something How about main() starts a thread that starts all the other threads? Then, thread_joinAll() would go inside the non-main :) thread. However, Steve is right: When main() exits, all threads will and should exit. Ali
Re: How to implement Canceleable spawn() from parent
On Tuesday, 30 June 2020 at 14:43:40 UTC, Steven Schveighoffer wrote: On 6/30/20 10:15 AM, Simen Kjærås wrote: [...] My thinking is I don't want regular consumers using the package to think about the technicality of thread_joinAll() at all. Thinking about putting it in a mixin like: mixin KeepRunning; Or something
Re: Progress printing with threads?
On Wednesday, 1 July 2020 at 07:52:28 UTC, AB wrote: Hello. I am unsure how to proceed about printing progress in my program. Suppose the program is processing a very big file and is iterating the file's bytes using a for loop. The processing takes several minutes and I want a progress percentage be printed every 2 seconds in this manner: Progress: 0.40% Progress: 3.20% Progress: 5.73% Is it a good idea to std.concurrency.spawn a new thread and pass to it cast(float)i * 100 / fileSize somehow? If not, what's a better way to do this? This example code shows my situation: MmFile input = new MmFile(/* ... */); ulong fileSize= input.length; for (ulong i = 0; i < fileSize; ++i) { // ... } Thanks in advance. If doing the update in the same thread that does the processing is somehow not an option, this works for me: import std.concurrency; import std.stdio; import core.thread; import core.time; void main() { ulong filesize = 1234; ulong i = 0; Tid progress = spawn((shared const(ulong)* p, ulong f){ while (!receiveTimeout(2000.msecs, (int i){ })) { writeln(*p, "/", f, ": ", *p*100.0/f, "%"); } }, cast(shared)&i, filesize); for (; i < filesize; ++i) { // Process } progress.send(0); // Stop } There's a cast to shared there which may be suboptimal, but since the progress thread is only reading it, I would say it's ok. -- Simen
Re: Progress printing with threads?
On Wednesday, 1 July 2020 at 07:52:28 UTC, AB wrote: Hello. I am unsure how to proceed about printing progress in my program. Is it a good idea to std.concurrency.spawn a new thread?.. This example code shows my situation: MmFile input = new MmFile(/* ... */); ulong fileSize= input.length; for (ulong i = 0; i < fileSize; ++i) { // ... } If you can only update the progress between iterations I don't see why you would use threads here. A timer should suffice: import std.datetime.stopwatch; MmFile input = new MmFile(/* ... */); ulong fileSize= input.length; autosw = StopWatch(AutoStart.yes); for (ulong i = 0; i < fileSize; ++i) { // ... if (sw.peek >= 2.seconds) { writefln("Progress: %5.2f%%", i*100.0/fileSize); sw.reset; } }
Re: Generating struct members from c structs
On Wednesday, 1 July 2020 at 07:26:44 UTC, Anthony wrote: When doing interop with a c library, is there a way to automatically generate the fields that are needed for a struct? [snip] Is there an easier way though? Dstep is probably what you're looking for: https://github.com/jacob-carlborg/dstep It eats C header files and creates appropriate D files from them. -- Simen
Progress printing with threads?
Hello. I am unsure how to proceed about printing progress in my program. Suppose the program is processing a very big file and is iterating the file's bytes using a for loop. The processing takes several minutes and I want a progress percentage be printed every 2 seconds in this manner: Progress: 0.40% Progress: 3.20% Progress: 5.73% Is it a good idea to std.concurrency.spawn a new thread and pass to it cast(float)i * 100 / fileSize somehow? If not, what's a better way to do this? This example code shows my situation: MmFile input = new MmFile(/* ... */); ulong fileSize= input.length; for (ulong i = 0; i < fileSize; ++i) { // ... } Thanks in advance.
Generating struct members from c structs
When doing interop with a c library, is there a way to automatically generate the fields that are needed for a struct? For example, when interfacing with the lwan c library: // lwan.h struct lwan { struct lwan_trie url_map_trie; struct lwan_connection *conns; struct lwan_strbuf headers; struct { pthread_barrier_t barrier; struct lwan_thread *threads; unsigned int max_fd; unsigned int count; } thread; struct lwan_config config; struct coro_switcher switcher; int main_socket; unsigned int n_cpus; }; module lwan; extern (C) { struct lwan { ... // <<< How do I populate this without having to write all the sub structs? }; void lwan_init(lwan* l); void lwan_shutdown(lwan* l); } import lwan; void main() { lwan l; //This is currently not allocating enough memory lwan_init(&l); lwan_shutdown(&l); } How do I populate the lwan struct without having to write all the sub structs? I'm thinking that maybe it'll be best to create a wrapper c function that initializes the lwan struct and returns a pointer. That way I don't have to declare any fields. extern (C) { struct lwan; lwan* lwan_make(); //wrapper function (perhaps in wrapper.c) void lwan_cleanup(lwan* l); //wrapper function void lwan_init(lwan* l); void lwan_shutdown(lwan* l); } Is there an easier way though?