Re: Why is this allowed

2020-07-01 Thread tsbockman via Digitalmars-d-learn

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

2020-07-01 Thread tsbockman via Digitalmars-d-learn

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

2020-07-01 Thread Dennis via Digitalmars-d-learn

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

2020-07-01 Thread JN via Digitalmars-d-learn

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

2020-07-01 Thread JN via Digitalmars-d-learn

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

2020-07-01 Thread Dennis via Digitalmars-d-learn

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

2020-07-01 Thread Dennis via Digitalmars-d-learn

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

2020-07-01 Thread Adam D. Ruppe via Digitalmars-d-learn

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

2020-07-01 Thread Stanislav Blinov via Digitalmars-d-learn

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

2020-07-01 Thread Dennis via Digitalmars-d-learn

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

2020-07-01 Thread Jacob Carlborg via Digitalmars-d-learn

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

2020-07-01 Thread Dennis via Digitalmars-d-learn
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

2020-07-01 Thread Steven Schveighoffer via Digitalmars-d-learn

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

2020-07-01 Thread Nathan S. via Digitalmars-d-learn

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

2020-07-01 Thread psycha0s via Digitalmars-d-learn

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 ,

2020-07-01 Thread Bruce Carneal via Digitalmars-d-learn

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

2020-07-01 Thread Ali Çehreli via Digitalmars-d-learn

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

2020-07-01 Thread aberba via Digitalmars-d-learn
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?

2020-07-01 Thread Simen Kjærås via Digitalmars-d-learn

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), 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?

2020-07-01 Thread Stanislav Blinov via Digitalmars-d-learn

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

2020-07-01 Thread Simen Kjærås via Digitalmars-d-learn

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?

2020-07-01 Thread AB via Digitalmars-d-learn
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

2020-07-01 Thread Anthony via Digitalmars-d-learn
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();
  lwan_shutdown();
}

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?



Re: scope guard question

2020-07-01 Thread Simen Kjærås via Digitalmars-d-learn
On Tuesday, 30 June 2020 at 12:18:14 UTC, Steven Schveighoffer 
wrote:
I can see where it would be confusing, and it could probably 
contain an example and clarification.


https://issues.dlang.org/show_bug.cgi?id=20997


Re: Program exited with code -11 when calling

2020-07-01 Thread Anthony via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 05:47:16 UTC, Anthony wrote:

On Wednesday, 1 July 2020 at 05:33:48 UTC, H. S. Teoh wrote:
On Wed, Jul 01, 2020 at 05:04:28AM +, Anthony via 
Digitalmars-d-learn wrote: [...]

auto str_utf8 = str.toUTF8();
bson_error_t error

auto bson = bson_new_from_json(cast(const 
uint8_t*)str_utf8.ptr, -1,

);


I get a "Program exited with code -11" message.
Does anyone know what I'm doing wrong?


D strings are generally not null-terminated (except for 
literals). Before passing them to a C function you need to add 
a trailing null. Try using std.conv.toStringz instead of 
casting the pointer yourself.



T


Thanks H. S. Teoh.
Hmm, still same result though.


import std.string;

auto str = toStringz("{\"a\":1}");

bson_error_t error;

bson_new_from_json(str, -1, );




extern(C) {
...
bson_t* bson_new_from_json(const char* data, long len, 
bson_error_t* error);

}


Noob mistake:
I declared an array that should be of fixed size.

struct bson_error_t {

char[] message;
};

Should be:

struct bson_error_t {

char[504] message;
};

:/