Re: Weird bug in std.logger? Possible memory corruption

2023-11-01 Thread Arafel via Digitalmars-d-learn

On 1/11/23 18:26, Christian Köstlin wrote:
It's really weird: https://run.dlang.io/is/fIBR2n 


I think I might have found out the issue. It's indeed related to the 
lazy parameter and reentrance.


The usual logger functions consist of three parts: a header, the 
message, and the "finalizer". [1]. Internally this is implemented using 
a string appender [2, 3].


However, this string appender is a member of the class, and this is the 
source of the bug, because it's shared among all the calls to the 
logger. It's usually protected by a mutex, so different threads don't 
mess with each other, but it didn't take reentrancy into account.


And so the call to the logging function within `foo` takes place once 
the appender is already populated, so this is what happens:


1. Header of first call to `log` (`info`, in this case, but it's 
irrelevant).

2. Body of first invocation -> Call to `foo()` -> Second call to `log`.
3. The buffer is cleared: The first header is discarded (and previous 
body, if there were any).
4. The second invocation proceeds normally, and the control returns to 
the first invocation
5. Now the buffer contains the full content of the previous call, and 
the return of `foo` is added.


This is exactly what we see. If we do an assignment **before**, then the 
call is no longer reentrant and everything happens as expected.


So I'd still call it a bug, but at least there seems to be no memory 
corruption. Also, it doesn't have an easy way to fix it without changing 
the interface (and potentially affecting already existing custom 
implementations).


In my view, `writeLogMsg` should create a brand new appender (not a 
member of the class) that would be passed as a parameter to 
`beginLogMsg`, `logMsgPart` and `finishLogMsg()`.


Anyway, I think the mystery is more or less solved.

[1]: https://dlang.org/phobos/std_logger_core.html#.Logger
[2]: https://github.com/dlang/phobos/blob/master/std/logger/core.d#L1401
[3]: https://github.com/dlang/phobos/blob/master/std/logger/core.d#L619-L641


Re: Weird bug in std.logger? Possible memory corruption

2023-11-01 Thread matheus via Digitalmars-d-learn
On Wednesday, 1 November 2023 at 17:26:42 UTC, Christian Köstlin 
wrote:

...
It's really weird: https://run.dlang.io/is/fIBR2n


Interesting because I wrote a similar test as you did. And that 
increment (Or lack of) called my attention, If I can I'll try and 
take a look at that (std.logger) info() Implementation later 
after work.


Matheus.


Re: Weird bug in std.logger? Possible memory corruption

2023-11-01 Thread Christian Köstlin via Digitalmars-d-learn

On Wednesday, 1 November 2023 at 14:15:55 UTC, matheus wrote:

On Tuesday, 31 October 2023 at 21:19:34 UTC, Arafel wrote:

...

Assigning the value to a variable works as expected:

```d
import std.logger : info;

void main() {
auto s = foo();
info(s);
}

auto foo() {
info("In foo");
return "Hello, world.";
}
```
...


Unless you do:

string s;
info(s=foo());

I think this is a bug, or at least very weird behavior.

Matheus.

It's really weird: https://run.dlang.io/is/fIBR2n



Re: Weird bug in std.logger? Possible memory corruption

2023-11-01 Thread matheus via Digitalmars-d-learn

On Tuesday, 31 October 2023 at 21:19:34 UTC, Arafel wrote:

...

Assigning the value to a variable works as expected:

```d
import std.logger : info;

void main() {
auto s = foo();
info(s);
}

auto foo() {
info("In foo");
return "Hello, world.";
}
```
...


Unless you do:

string s;
info(s=foo());

I think this is a bug, or at least very weird behavior.

Matheus.


Re: Weird bug in std.logger? Possible memory corruption

2023-11-01 Thread Arafel via Digitalmars-d-learn
I can only imagine that it's related to the logging functions taking 
lazy arguments, although I cannot see why it would be a problem in a 
simple case like this.


I've been thinking a bit more about it, and it must be indeed because of 
the lazy argument.


`foo()` is an argument to `info`, but it also uses the logger. However, 
because it's a lazy argument, it's not called from `main`, but from 
`info` itself. I strongly suspect that the problem is that it's not 
reentrant.


I'm not clear what it's supposed to happen, but assuming this case won't 
be supported, it should at least be documented. Should I open a bug 
about it?


Weird bug in std.logger? Possible memory corruption

2023-10-31 Thread Arafel via Digitalmars-d-learn

Hi,

Today I have just found a weird bug in std.logger. Consider:

```d
import std.logger : info;

void main() {
info(foo());
}

auto foo() {
info("In foo");
return "Hello, world.";
}
```

The output is:

```
2023-10-31T20:41:05.274 [info] onlineapp.d:8:foo In foo
2023-10-31T20:41:05.274 [info] onlineapp.d:8:foo In fooHello, world.
```

The second line is obviously wrong, as it repeats the first line as its 
header. That's why I suspect memory corruption.


Assigning the value to a variable works as expected:

```d
import std.logger : info;

void main() {
auto s = foo();
info(s);
}

auto foo() {
info("In foo");
return "Hello, world.";
}
```

gets the proper output:

```
2023-10-31T21:09:46.529 [info] onlineapp.d:9:foo In foo
2023-10-31T21:09:46.529 [info] onlineapp.d:5:main Hello, world.
```

I can only imagine that it's related to the logging functions taking 
lazy arguments, although I cannot see why it would be a problem in a 
simple case like this.


Re: Weird floating point rounding - Bug or how to control it correctly

2023-09-13 Thread Basile B. via Digitalmars-d-learn

On Thursday, 14 September 2023 at 03:23:48 UTC, An Pham wrote:

import std.stdio;

void main()
{
float f = 6394763.345f;

import std.format : sformat;

char[80] vBuffer = void;
writeln("6394763.345 = ", sformat(vBuffer[], "%.4f", 
f));


}

Output
6394763.345 = 6394763.5000


Classic question. The float literal `6394763.345f` is not 
representable as IEEE-754 floating point number.


Try https://www.h-schmidt.net/FloatConverter/IEEE754.html for a 
short introduction to the issue.


Re: Weird floating point rounding - Bug or how to control it correctly

2023-09-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, September 13, 2023 9:23:48 PM MDT An Pham via Digitalmars-d-
learn wrote:
> import std.stdio;
>
>  void main()
>  {
>  float f = 6394763.345f;
>
>  import std.format : sformat;
>
>  char[80] vBuffer = void;
>  writeln("6394763.345 = ", sformat(vBuffer[], "%.4f", f));
>
>  }
>
> Output
> 6394763.345 = 6394763.5000

The nature of floating point numbers is such that there a bunch of values
that they can't actually represent, and they get rounded pretty easily
depending on the exact numbers involved. So, in general, you shouldn't
expect floating point numbers to be exact. You will generally do better with
increased precision though, and in this case, it looks like your number will
stay the same if you use double or real instead of float.

I would suggest that you watch this video from dconf 2016 which discusses
floating point values:

https://www.youtube.com/watch?v=YEUAUnamQiA

- Jonathan M Davis





Weird floating point rounding - Bug or how to control it correctly

2023-09-13 Thread An Pham via Digitalmars-d-learn

import std.stdio;

void main()
{
float f = 6394763.345f;

import std.format : sformat;

char[80] vBuffer = void;
writeln("6394763.345 = ", sformat(vBuffer[], "%.4f", f));

}

Output
6394763.345 = 6394763.5000


Re: Bug in usage of associative array: dynamic array with string as a key

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

On 6/30/23 17:42, Cecil Ward wrote:

> https://dlang.org/spec/hash-map.html#testing_membership in the language
> docs, under associative arrays - 13.3 testing membership. Would anyone
> else care to try that example out as that might be quicker?

I tried it by

1) Putting all the code inside a 'void main()' function
2) Pasting the code from the top of that page

and it works:

void main() {
int[string] aa;   // Associative array of ints that are
// indexed by string keys.
// The KeyType is string.
aa["hello"] = 3;  // set value associated with key "hello" to 3
int value = aa["hello"];  // lookup value from a key
assert(value == 3);
int* p;

p = "hello" in aa;
if (p !is null)
{
*p = 4;  // update value associated with key
assert(aa["hello"] == 4);
}
}

> the only substantive
> change being deleting the variable p

Do you mean this:

aa.remove("hello");

That works too.

D's associative arrays have a few quirks but they work just fine. They 
are not buggy as it may be inferred from some of the posts here.


Ali



Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote:

I have code roughly like the following:

   dstring str = "name"d;
   uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
Decls.ordinals[ str ]  :  -1;


struct Decls
   {
   uint[ dstring]   ordinals;
   }

//and
   Decls.ordinals[ str ] = ordinal_counter++;

The problem is that it always returns ordinal== -1 from the 
expression. Can you sort me out? I took this from the example 
given in the language reference under arrays, testing for 
membership (or similar, I forget the subssection title).


From good old printfs it seems to be the case that the array is 
being populated (elsewhere) with the expected correct values. 
Taking out the if doesn’t seem to help either. I don’t have a 
way of examining the contents of the dynamic array directly to 
check that they are actually being stored as expected, other 
than seeing that that line of code is indeed being executed 
with the expected values of str going in. Note that I’m using 
32-bit dstrings everywhere, not strings of bytes.


Fool that I am. I did those good old printfs a while back, and 
now I recheck them I see that something has become broken and it 
seems that the insertions are not happening now. So thankyou for 
your kindness and I’ll post again if that doesn’t solve the 
non-issue.


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 30 June 2023 at 21:25:23 UTC, H. S. Teoh wrote:
On Fri, Jun 30, 2023 at 07:05:23PM +, Cecil Ward via 
Digitalmars-d-learn wrote: [...]


It would help if you could post the complete code that 
reproduces the problem. Or, if you do not wish to reveal your 
code, reduce it to a minimal case that still exhibits the same 
problem, so that we can see it for ourselves.  The snippets you 
provided do not provide enough information to identify the 
problem.



T


I would indeed need to cut it down massively, as the original 
code is ~2k lines. Mind you, I will just end up with the example 
at https://dlang.org/spec/hash-map.html#testing_membership in the 
language docs, under associative arrays - 13.3 testing 
membership. Would anyone else care to try that example out as 
that might be quicker? That’s because as all I did was copy that 
basically, with the only substantive change being deleting the 
variable p, but I’m still testing whether or not I get a null 
pointer.


I thought I had checked that the insertions were all as expected, 
so I’ll go and recheck that next.


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread mw via Digitalmars-d-learn

https://forum.dlang.org/thread/duetqujuoceancqtj...@forum.dlang.org

Try HashMap see if it is still a problem.

If no, then it's another example of the built in AA problem.


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 30, 2023 at 07:05:23PM +, Cecil Ward via Digitalmars-d-learn 
wrote:
[...]

It would help if you could post the complete code that reproduces the
problem. Or, if you do not wish to reveal your code, reduce it to a
minimal case that still exhibits the same problem, so that we can see it
for ourselves.  The snippets you provided do not provide enough
information to identify the problem.


T

-- 
What's the difference between a 4D tube and an overweight Dutchman?  One
is a hollow spherinder, and the other is a spherical Hollander.


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Ali Çehreli via Digitalmars-d-learn

On 6/30/23 13:16, Cecil Ward wrote:

On Friday, 30 June 2023 at 19:58:39 UTC, FeepingCreature wrote:



Note that you can do `uint ordinal = Decls.ordinals.get(str, -1);`.


Is the second argument an ‘else’ then, my friend?


Yes, .get and friends appear in this table:

  https://dlang.org/spec/hash-map.html#properties

Ali



Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 30 June 2023 at 19:58:39 UTC, FeepingCreature wrote:

On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote:

I have code roughly like the following:

   dstring str = "name"d;
   uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
Decls.ordinals[ str ]  :  -1;


struct Decls
   {
   uint[ dstring]   ordinals;
   }

//and
   Decls.ordinals[ str ] = ordinal_counter++;

The problem is that it always returns ordinal== -1 from the 
expression. Can you sort me out?


Impossible to tell without a complete repro, I'm afraid. The 
expression, at least, looks correct at first glance.


Note that you can do `uint ordinal = Decls.ordinals.get(str, 
-1);`.


Is the second argument an ‘else’ then, my friend?


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 30 June 2023 at 20:12:08 UTC, Ali Çehreli wrote:

On 6/30/23 12:05, Cecil Ward wrote:
> I have code roughly like the following:
>
> dstring str = "name"d;

Aside: One almost never needs dstring.

> uint ordinal =  (( str in Decls.ordinals ) !is null)  ?
> Decls.ordinals[ str ]  :  -1;
>
> struct Decls
> {
> uint[ dstring]   ordinals;

Do you mean 'ordinals' is 'static'? Otherwise, Decls.ordinals 
does not compile.


> }
>
> //and
> Decls.ordinals[ str ] = ordinal_counter++;

Are you doing that *after* you initialize 'ordinal' as you show 
here? :)


Ali


Hi Ali, ‘ordinal’ is a static initialised explicitly with zero.


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Ali Çehreli via Digitalmars-d-learn

On 6/30/23 12:05, Cecil Ward wrote:
> I have code roughly like the following:
>
> dstring str = "name"d;

Aside: One almost never needs dstring.

> uint ordinal =  (( str in Decls.ordinals ) !is null)  ?
> Decls.ordinals[ str ]  :  -1;
>
> struct Decls
> {
> uint[ dstring]   ordinals;

Do you mean 'ordinals' is 'static'? Otherwise, Decls.ordinals does not 
compile.


> }
>
> //and
> Decls.ordinals[ str ] = ordinal_counter++;

Are you doing that *after* you initialize 'ordinal' as you show here? :)

Ali



Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread FeepingCreature via Digitalmars-d-learn

On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote:

I have code roughly like the following:

   dstring str = "name"d;
   uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
Decls.ordinals[ str ]  :  -1;


struct Decls
   {
   uint[ dstring]   ordinals;
   }

//and
   Decls.ordinals[ str ] = ordinal_counter++;

The problem is that it always returns ordinal== -1 from the 
expression. Can you sort me out?


Impossible to tell without a complete repro, I'm afraid. The 
expression, at least, looks correct at first glance.


Note that you can do `uint ordinal = Decls.ordinals.get(str, 
-1);`.


Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

I have code roughly like the following:

   dstring str = "name"d;
   uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
Decls.ordinals[ str ]  :  -1;


struct Decls
   {
   uint[ dstring]   ordinals;
   }

//and
   Decls.ordinals[ str ] = ordinal_counter++;

The problem is that it always returns ordinal== -1 from the 
expression. Can you sort me out? I took this from the example 
given in the language reference under arrays, testing for 
membership (or similar, I forget the subssection title).


From good old printfs it seems to be the case that the array is 
being populated (elsewhere) with the expected correct values. 
Taking out the if doesn’t seem to help either. I don’t have a way 
of examining the contents of the dynamic array directly to check 
that they are actually being stored as expected, other than 
seeing that that line of code is indeed being executed with the 
expected values of str going in. Note that I’m using 32-bit 
dstrings everywhere, not strings of bytes.




Re: looking for hint to debug a strange multi-thread bug (grpc-d-core)

2023-06-13 Thread mw via Digitalmars-d-learn
UPDATE: life is too short to debug dlang built-in AA to right, 
let's just use HashMap from emsi_containers


https://github.com/mw66/grpc-d/blob/master/source/grpc/server/package.d#L25
```
HashMap!(string, ServiceHandlerInterface) services;
```

After this change, the problem goes away.

I think there are some bugs in the builtin AA implementation, as 
demo-ed in this multi-threaded program (maybe also related to 
GC?).




looking for hint to debug a strange multi-thread bug (grpc-d-core)

2023-06-13 Thread mw via Digitalmars-d-learn

Hi,

I recently found and started playing with the grpc-d-core[1] 
package, and my program structure looks like this:


https://github.com/mw66/grpc-demo/blob/master/source/main.d

If I run L64 alone (without L66 ~ 79 grpc-d part):
```
64: auto t = new Thread({fun();}).start();
```
it works fine.

If I run L66 ~ 79 grpc-d part alone (without L64), it also works 
fine.


But if I run both, the program received signal SIGSEGV, 
Segmentation fault at here:


https://github.com/mw66/grpc-d/blob/master/source/grpc/server/package.d#L94

with LDC, the print out of `services.keys` shows its corrupted 
with some strange values.


under DMD, it fails at:

https://github.com/mw66/grpc-d/blob/master/source/grpc/server/package.d#L99

while the `services.keys` seems fine.

What puzzles me is that: these two parts of the code are actually 
independent, does not know each other at all (as I just started 
to add the grpc-d skeleton code with dummy returns, and no client 
connected or made any rpc calls).


And the `services` defined here is a private class field:

https://github.com/mw66/grpc-d/blob/master/source/grpc/server/package.d#L21

So how can it be corrupted by `fun()`?


Any suggestions where should I look into?

Thanks.


[1] https://code.dlang.org/packages/grpc-d-core




Re: Is this a bug?

2023-03-15 Thread Elfstone via Digitalmars-d-learn

On Thursday, 16 March 2023 at 04:31:11 UTC, Elfstone wrote:

On Thursday, 16 March 2023 at 04:04:51 UTC, Elfstone wrote:

On Thursday, 16 March 2023 at 03:44:19 UTC, Elfstone wrote:

[...]


Correction.

With or without comments, mostly it doesn't compile, 
occasionally it does!

I have no idea.


I can't get it to compile anymore, it must be some mistake from 
me. Maybe I forgot to save   while modifying the code.


So the `S` declared in `is` expression can contaminate the 
scope? Is this supposed to happen?


Never mind, I just found out this is supposed to happen, `S` is 
supposed to be available later.


https://dlang.org/spec/expression.html#is-parameter-list


Re: Is this a bug?

2023-03-15 Thread Elfstone via Digitalmars-d-learn

On Thursday, 16 March 2023 at 04:04:51 UTC, Elfstone wrote:

On Thursday, 16 March 2023 at 03:44:19 UTC, Elfstone wrote:

On Thursday, 16 March 2023 at 03:40:04 UTC, Elfstone wrote:

[...]


Oops, the above code compiles, because I added comments!!!

Now this really doesn't compile:

```D
struct Matrix(S, size_t M, size_t N)
{
}

alias Vec3(S) = Matrix!(S, 3, 1);

void main()
{
import std.stdio;

writeln(is(Vec3!float == Matrix!(S, 3, 1), S));
writeln(is(Matrix!(float, 3, 1) == Matrix!(S, 3, 1), S));
}
```


Correction.

With or without comments, mostly it doesn't compile, 
occasionally it does!

I have no idea.


I can't get it to compile anymore, it must be some mistake from 
me. Maybe I forgot to save   while modifying the code.


So the `S` declared in `is` expression can contaminate the scope? 
Is this supposed to happen?




Re: Is this a bug?

2023-03-15 Thread Elfstone via Digitalmars-d-learn

On Thursday, 16 March 2023 at 03:44:19 UTC, Elfstone wrote:

On Thursday, 16 March 2023 at 03:40:04 UTC, Elfstone wrote:

[...]


Oops, the above code compiles, because I added comments!!!

Now this really doesn't compile:

```D
struct Matrix(S, size_t M, size_t N)
{
}

alias Vec3(S) = Matrix!(S, 3, 1);

void main()
{
import std.stdio;

writeln(is(Vec3!float == Matrix!(S, 3, 1), S));
writeln(is(Matrix!(float, 3, 1) == Matrix!(S, 3, 1), S));
}
```


Correction.

With or without comments, mostly it doesn't compile, occasionally 
it does!

I have no idea.


Is this a bug?

2023-03-15 Thread Elfstone via Digitalmars-d-learn

```D
struct Matrix(S, size_t M, size_t N)
{
}

alias Vec3(S) = Matrix!(S, 3, 1);

void main()
{
import std.stdio;

writeln(is(Vec3!float == Matrix!(S, 3, 1), S)); // `alias` 
`S` is defined here
writeln(is(Matrix!(float, 3, 1) == Matrix!(S, 3, 1), S)); // 
Error: declaration `S` is already defined

}
```

Even though the following code compiles.

```D
writeln(is(Vec3!float == Matrix!(S, 3, 1), S));
writeln(is(Vec3!float == Matrix!(S, 3, 1), S));
```


Re: Is this a bug?

2023-03-15 Thread Elfstone via Digitalmars-d-learn

On Thursday, 16 March 2023 at 03:40:04 UTC, Elfstone wrote:

```D
struct Matrix(S, size_t M, size_t N)
{
}

alias Vec3(S) = Matrix!(S, 3, 1);

void main()
{
import std.stdio;

writeln(is(Vec3!float == Matrix!(S, 3, 1), S)); // `alias` 
`S` is defined here
writeln(is(Matrix!(float, 3, 1) == Matrix!(S, 3, 1), S)); 
// Error: declaration `S` is already defined

}
```

Even though the following code compiles.

```D
writeln(is(Vec3!float == Matrix!(S, 3, 1), S));
writeln(is(Vec3!float == Matrix!(S, 3, 1), S));
```


Oops, the above code compiles, because I added comments!!!

Now this really doesn't compile:

```D
struct Matrix(S, size_t M, size_t N)
{
}

alias Vec3(S) = Matrix!(S, 3, 1);

void main()
{
import std.stdio;

writeln(is(Vec3!float == Matrix!(S, 3, 1), S));
writeln(is(Matrix!(float, 3, 1) == Matrix!(S, 3, 1), S));
}
```


Re: Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn
On Friday, 3 March 2023 at 01:37:42 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

On 03/03/2023 2:33 PM, ryuukk_ wrote:

So it is a DMD bug?


Yes and thanks to you I can now say that we can absolutely get 
rid of DllMain requirement for DLLs!


glad the outcome is positive, and i apologies about earlier 
comments, i may have sounded a little bit rude





Re: Bug in DMD?

2023-03-02 Thread Vladimir Panteleev via Digitalmars-d-learn

On Friday, 3 March 2023 at 01:21:52 UTC, ryuukk_ wrote:

I have some questions:

1. why does it work with LDC?
2. why does it work with DMD when build/link in 2 step?
3. why it doesn't work when DMD is invoked once for build/link


I think these are probably coincidences and the answer can be 
summarized as "that's what ends up happening due to the details 
of the implementation".



4. is this a bug in DMD or my code is wrong?


I would say the code is wrong in principle, though as you've 
noted it can still work in some specific circumstances.



5. if it's wrong, then why does it compile/no error?


`extern(C) main` is a low-level feature, because it effectively 
turns off parts of the language. However, the rest of the program 
doesn't know that this is the case - currently the compiler 
simply assumes you know what you're doing. Maybe it's not OK that 
it's easy to use it by accident.




Re: Bug in DMD?

2023-03-02 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

I added a note here: https://issues.dlang.org/show_bug.cgi?id=20737


Re: Bug in DMD?

2023-03-02 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 03/03/2023 2:33 PM, ryuukk_ wrote:

So it is a DMD bug?


Yes and thanks to you I can now say that we can absolutely get rid of 
DllMain requirement for DLLs!


Re: Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn
On Friday, 3 March 2023 at 01:24:42 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

This works:

```d
extern(C) void main()
{
Stuff[5] temp = [
Stuff(),
Stuff(),
Stuff(),
Stuff(),
Stuff(),
];
stuffs = temp[];
stuffs[0].do_something();
}
```

```d
Stuff[] stuffs;
```

The problem here is dmd isn't initializing TLS with a value, 
but TLS itself is working.


So it is a DMD bug?


Re: Bug in DMD?

2023-03-02 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

This works:

```d
extern(C) void main()
{
Stuff[5] temp = [
Stuff(),
Stuff(),
Stuff(),
Stuff(),
Stuff(),
];
stuffs = temp[];
stuffs[0].do_something();
}
```

```d
Stuff[] stuffs;
```

The problem here is dmd isn't initializing TLS with a value, but TLS 
itself is working.


Re: Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn

On Friday, 3 March 2023 at 01:11:06 UTC, Vladimir Panteleev wrote:

On Friday, 3 March 2023 at 01:07:07 UTC, ryuukk_ wrote:
I couldn't figure out dustmite, so i started from 0 and 
managed to hit something:


https://github.com/ryuukk/dmd_bug

``Assertion failed: array index out of bounds, file 
game\app.d, line 5``


Wich indicates probably TLS problem?


Yeah... `rt.a.stuffs` is a TLS variable. The D runtime manages 
TLS. `extern(C) main` bypasses D runtime initialization.


I have some questions:

1. why does it work with LDC?
2. why does it work with DMD when build/link in 2 step?
3. why it doesn't work when DMD is invoked once for build/link
4. is this a bug in DMD or my code is wrong?
5. if it's wrong, then why does it compile/no error?


```sh
#!/usr/bin/env bash

set -e

build_dmd() {
echo "build dmd"
dmd \
-debug -g \
-m64 -vcolumns -betterC -w -i -i=-std -i=-core \
-Igame \
-Istuff/ \
stuff/rt/object.d \
game/app.d \
-of=game.exe
}

build_ldc() {
echo "build ldc"
ldc2 \
-d-debug -g \
-m64 -vcolumns -betterC -w -i -i=-std -i=-core \
-Igame \
-Istuff/ \
stuff/rt/object.d \
game/app.d \
-of=game.exe
}

build_dmd_and_link() {
echo "build dmd and link (2step)"
dmd \
-debug -g -c \
-m64 -vcolumns -betterC -w -i -i=-std -i=-core \
-Igame \
-Istuff/ \
stuff/rt/object.d \
game/app.d \
-of=game.obj

dmd \
-debug -g  \
-m64 -vcolumns -betterC -w -i -i=-std -i=-core \
-Igame \
-Istuff/ \
game.obj \
-of=game.exe
}


build_ldc
./game.exe
rm game.obj game.exe

build_dmd_and_link
./game.exe
rm game.obj game.exe

build_dmd
./game.exe
rm game.obj game.exe
```


Re: Bug in DMD?

2023-03-02 Thread Vladimir Panteleev via Digitalmars-d-learn

On Friday, 3 March 2023 at 01:07:07 UTC, ryuukk_ wrote:
I couldn't figure out dustmite, so i started from 0 and managed 
to hit something:


https://github.com/ryuukk/dmd_bug

``Assertion failed: array index out of bounds, file game\app.d, 
line 5``


Wich indicates probably TLS problem?


Yeah... `rt.a.stuffs` is a TLS variable. The D runtime manages 
TLS. `extern(C) main` bypasses D runtime initialization.




Re: Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn
I couldn't figure out dustmite, so i started from 0 and managed 
to hit something:


https://github.com/ryuukk/dmd_bug

``Assertion failed: array index out of bounds, file game\app.d, 
line 5``


Wich indicates probably TLS problem?

This now reminds me of: 
https://issues.dlang.org/show_bug.cgi?id=23310


I am clueless what to do next, but at least now there is a small 
repro available for knowledgeable people


Re: Bug in DMD?

2023-03-02 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 03/03/2023 10:38 AM, ryuukk_ wrote:
On Thursday, 2 March 2023 at 21:21:14 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

There isn't anything we can do without source.

But here is what I would do in this situation:

1. Look at the assembly at the point of debug break, from here it 
should give you hints as to why its trying to write to 
dawn.assets.Resource init array.

2. Dustmite, so we have something we can work with.


I have no idea what does 1. mean, as for 2. do you have a link for a 
guide how to setup "dustmite"?


When debugging, native debuggers i.e. Visual Studio, will provide you 
with the disassembly of the function currently being executed. Between 
this and other entries in the call stack, you can generally figure out 
what the statement is being executed just by looking at things like call 
instructions. The symbols there will be accurate.


Re: Bug in DMD?

2023-03-02 Thread Ali Çehreli via Digitalmars-d-learn

On 3/2/23 15:34, ryuukk_ wrote:

> the problem is not that it can run in the background, the problem is
> figuring out
>
> 1. how to install
> 2. how to setup
> 3. how to run

I haven't used it myself but dustmite seems to be integrated into dub. 
'dub dustmite <...>'


Ali



Re: Bug in DMD?

2023-03-02 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 03/03/2023 12:34 PM, ryuukk_ wrote:

1. how to install


Already is.

Comes with dmd and ldc.

You can also just do ``$ dub run digger -- args``.


2. how to setup > 3. how to run


It is a bit of a pain but the basics is you need some sort of 
compilation command, list of sources and a test to confirm if it still 
fails.


https://github.com/CyberShadow/DustMite/wiki#how-to-use-it


Re: Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn

On Thursday, 2 March 2023 at 22:24:11 UTC, H. S. Teoh wrote:
On Thu, Mar 02, 2023 at 09:55:55PM +, ryuukk_ via 
Digitalmars-d-learn wrote:

On Thursday, 2 March 2023 at 21:38:23 UTC, ryuukk_ wrote:
> On Thursday, 2 March 2023 at 21:21:14 UTC, Richard (Rikki) 
> Andrew

> Cattermole wrote:

[...]

> > 2. Dustmite, so we have something we can work with.
> 
> [...] 2. do you have a link for a guide how to setup 
> "dustmite"?


https://dlang.org/blog/2020/04/13/dustmite-the-general-purpose-data-reduction-tool/

Dustmite automatically reduces your code to a minimal example 
that still exhibits the same problem, good for bug reports that 
are easily reproducible.  Also useful if you don't want to 
publicly share the code for whatever reason, but still want to 
provide enough information so that the dmd devs can find the 
problem and fix it.



[...]
That's is not something i like doing, it should just work, i 
shouldn't have to debug DMD, that aint my job


Dustmite can run in the background on a temporary copy of your 
code, you don't have to babysit it and can work on other things 
while it's doing its thing.



T


the problem is not that it can run in the background, the problem 
is figuring out


1. how to install
2. how to setup
3. how to run

i was initially working on my game, i shouldn't have to take a 1 
week break to debug dmd


Re: Bug in DMD?

2023-03-02 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Mar 02, 2023 at 09:55:55PM +, ryuukk_ via Digitalmars-d-learn wrote:
> On Thursday, 2 March 2023 at 21:38:23 UTC, ryuukk_ wrote:
> > On Thursday, 2 March 2023 at 21:21:14 UTC, Richard (Rikki) Andrew
> > Cattermole wrote:
[...]
> > > 2. Dustmite, so we have something we can work with.
> > 
> > [...] 2. do you have a link for a guide how to setup "dustmite"?

https://dlang.org/blog/2020/04/13/dustmite-the-general-purpose-data-reduction-tool/

Dustmite automatically reduces your code to a minimal example that still
exhibits the same problem, good for bug reports that are easily
reproducible.  Also useful if you don't want to publicly share the code
for whatever reason, but still want to provide enough information so
that the dmd devs can find the problem and fix it.


[...]
> That's is not something i like doing, it should just work, i shouldn't
> have to debug DMD, that aint my job

Dustmite can run in the background on a temporary copy of your code, you
don't have to babysit it and can work on other things while it's doing
its thing.


T

-- 
Written on the window of a clothing store: No shirt, no shoes, no service.


Re: Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn

On Thursday, 2 March 2023 at 21:38:23 UTC, ryuukk_ wrote:
On Thursday, 2 March 2023 at 21:21:14 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

There isn't anything we can do without source.

But here is what I would do in this situation:

1. Look at the assembly at the point of debug break, from here 
it should give you hints as to why its trying to write to 
dawn.assets.Resource init array.

2. Dustmite, so we have something we can work with.


I have no idea what does 1. mean, as for 2. do you have a link 
for a guide how to setup "dustmite"?


Better, can i send you a zip of my project? i'm not sure i'm 
willing to waste any more time trying to figure out what is wrong


That's is not something i like doing, it should just work, i 
shouldn't have to debug DMD, that aint my job


Re: Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn
On Thursday, 2 March 2023 at 21:21:14 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

There isn't anything we can do without source.

But here is what I would do in this situation:

1. Look at the assembly at the point of debug break, from here 
it should give you hints as to why its trying to write to 
dawn.assets.Resource init array.

2. Dustmite, so we have something we can work with.


I have no idea what does 1. mean, as for 2. do you have a link 
for a guide how to setup "dustmite"?


Re: Bug in DMD?

2023-03-02 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

There isn't anything we can do without source.

But here is what I would do in this situation:

1. Look at the assembly at the point of debug break, from here it should 
give you hints as to why its trying to write to dawn.assets.Resource 
init array.

2. Dustmite, so we have something we can work with.


Re: Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn
It crashes with a weird message, address doesn't match the 
mangled name:


``C:\dev\kdom\projects\dawn\gl\glad\loader.d``

inside: ``module dawn.gl.glad.loader;``

![screenshot](https://i.imgur.com/sY2KcgR.png)


Bug in DMD?

2023-03-02 Thread ryuukk_ via Digitalmars-d-learn

Hello,

I encountered a weird issue, my program segfault when i feed DMD 
with my files and static libs


It doesn't when i compile with LDC

If i split the compile/link in 2 different steps, then all works 
correctly



DMD (1step: ⛔): 
https://gist.github.com/ryuukk/f0ae2ae0c8980219c04d0c6d8678940d


LDC (1step: ✅): 
https://gist.github.com/ryuukk/4c7706697583431389d5e2074548f7c4


DMD (2step: ✅): 
https://gist.github.com/ryuukk/a0373339e590ecdae91e3f05b2d81bf4



Looks like DMD is messing things up when mixing code with static 
libraries?




Toolchains:
  - DMD32 D Compiler v2.102.1
  - LDC - the LLVM D compiler (1.32.0-beta1):


Re: Bug or feature? iota has different semantics for integer and float arguments

2023-01-07 Thread Arredondo via Digitalmars-d-learn

On Saturday, 7 January 2023 at 02:31:14 UTC, Ali Çehreli wrote:

On 1/6/23 17:50, Arredondo wrote:

> Would anyone volunteer to file a bug report?

Me! Me! :)

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

Ali


Thanks a lot :D

Arredondo.


Re: Bug or feature? iota has different semantics for integer and float arguments

2023-01-06 Thread Ali Çehreli via Digitalmars-d-learn

On 1/6/23 17:50, Arredondo wrote:

> Would anyone volunteer to file a bug report?

Me! Me! :)

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

Ali



Re: Bug or feature? iota has different semantics for integer and float arguments

2023-01-06 Thread Arredondo via Digitalmars-d-learn

On Saturday, 7 January 2023 at 00:52:20 UTC, Ali Çehreli wrote:
Although that difference is a bug, iota does have a special 
floating point implementation to prevent the accumulation of 
floating point errors.


Thank you for this clarification Ali. I appreciate the fact that 
there is a specialized implementation for float types in an 
attempt to mitigate error accumulation.


After posting my previous message I became convinced that the 
behavior I was seeing was indeed a bug. The specialized fp 
implementation simply does not conform to the semantics specified 
in the documentation: "If begin < end && step < 0 or begin > end 
&& step > 0 or begin == end, then an empty range is returned."


The culprit is this assert in the `in` block of the fp 
implementation:


```
assert((end - begin) / step >= 0, "iota: incorrect startup 
parameters");

```

This effectively prevents iota from ever returning an empty 
range. Git blame points to a commit from March 2015. It's 
unbelievable to me this hasn't been fixed in almost 8 years.


Would anyone volunteer to file a bug report? I attempted to do it 
myself but I would need to create an account in the Issue 
Tracking System, and apparently it doesn't accept gmail addresses 
anymore? (facepalm).


Arredondo.


Re: Bug or feature? iota has different semantics for integer and float arguments

2023-01-06 Thread Ali Çehreli via Digitalmars-d-learn

On 1/6/23 15:23, Arredondo wrote:

> then you get an exception (incorrect startup parameters).

Although that difference is a bug, iota does have a special floating 
point implementation to prevent the accumulation of floating point 
errors. I mention it as item 4 here:


  https://www.youtube.com/watch?v=gwUcngTmKhg=634s

Briefly, iota's regular popFront() is a trivial

  front += step

but it is

  ++n

for floating types so that front can be

  begin + (n * step)

for them.

The iota discussion starts at an earlier point in the video here:

  https://www.youtube.com/watch?v=gwUcngTmKhg=558s

Ali



Bug or feature? iota has different semantics for integer and float arguments

2023-01-06 Thread Arredondo via Digitalmars-d-learn

Consider:

```
import std.range.iota;
auto r = iota(5, 0);
```

`r` is an empty range, as it should be. But if you call:

```
auto r = iota(5.0, 0);
```

then you get an exception (incorrect startup parameters).

This was unexpected, and a pain to debug. What is the rationale 
behind iota having different semantics depending on whether the 
arguments are floats or not?


Arredondo.


Re: pointer escaping return scope bug?

2022-12-18 Thread j via Digitalmars-d-learn
On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven 
wrote:

Hi,
The following seems like a bug to me (reduced code, FILE* 
changed to int*):

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```
There's no error with -dip1000.
I'll file this unless I overlooked something.




The state of the memory can not be guaranteed by the compiler. 
That is the responsibility of the programmer. When a pointer gets 
over-written the memory it was pointing to remains owne by the 
program. It could be accesible by recovering the pointer. If you 
want to destroy the memory there are various ways of doing this 
depending on your performance needs. D has an optional garbage 
collector by default.


Re: Unique!struct bug - Re: unique_ptr | Unique for autoclose handle

2022-12-16 Thread Nick Treleaven via Digitalmars-d-learn

On Thursday, 15 December 2022 at 20:12:12 UTC, Ali Çehreli wrote:
I think this is a bug because the documentation clearly talks 
about destroying the object:


OK: https://github.com/dlang/phobos/pull/8651


>  do we need to do some kind of deprecation?

The behavior is so different from the intention that I don't 
think anybody is using Unique anyway. :o)


Yes, at least for structs.


Re: Unique!struct bug - Re: unique_ptr | Unique for autoclose handle

2022-12-15 Thread Ali Çehreli via Digitalmars-d-learn

On 12/15/22 11:31, Nick Treleaven wrote:
> On Wednesday, 14 December 2022 at 17:41:07 UTC, Ali Çehreli wrote:
>> I've never used Unique but I think it has a bug (or a design issue?):
>> Its destructor is the following:
>>
>> ~this()
>> {
>> if (_p !is null)
>> {
>> destroy(_p);
>> _p = null;
>> }
>> }
>>
>> Because _p is a pointer, destroy(_p) will not dereference and destroy
>> what it points to. I think this is a bug with Unique. I think it
>> should do
>>
>>   destroy(*_p);
>
> Now filed:
> https://issues.dlang.org/show_bug.cgi?id=23561

Thanks. I was hoping others more experienced with Phobos implementation 
chime in. But to me, the intention is to destroy the object. One never 
wants to destroy a pointer as there is no operation there.


As a minor proud moment, I do cover this issue:

  http://ddili.org/ders/d.en/memory.html#ix_memory.destroy

> Do you think it's OK to just fix this or

I think this is a bug because the documentation clearly talks about 
destroying the object:


  https://dlang.org/library/std/typecons/unique.html

"When a Unique!T goes out of scope it will call destroy on the
resource T that it manages, unless it is transferred. One
important consequence of destroy is that it will call the
destructor of the resource T."

>  do we need to do some kind of deprecation?

The behavior is so different from the intention that I don't think 
anybody is using Unique anyway. :o)


Ali



Re: pointer escaping return scope bug?

2022-12-15 Thread Nick Treleaven via Digitalmars-d-learn
On Thursday, 15 December 2022 at 20:02:38 UTC, Nick Treleaven 
wrote:

auto f() return @trusted => p ? p : v.ptr;


Whoops, that can't be @trusted unless I `assert(p)`.


Re: pointer escaping return scope bug?

2022-12-15 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 19 November 2022 at 15:24:33 UTC, Dukc wrote:
On Saturday, 19 November 2022 at 15:02:54 UTC, Nick Treleaven 
wrote:

OK, so how do I make `lf` implicitly scope?


Have the `int*` inside it to point to a local, or assign 
another `scope int*` to it.


Thanks, this works:

```d
@safe:

struct S
{
int* p;
int[0] v; // dummy storage
auto f() return @trusted => p ? p : v.ptr;
}

void main()
{
int* p;
{
S s = S(new int);
p = s.f; // error
}
}
```


Unique!struct bug - Re: unique_ptr | Unique for autoclose handle

2022-12-15 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 14 December 2022 at 17:41:07 UTC, Ali Çehreli wrote:
I've never used Unique but I think it has a bug (or a design 
issue?): Its destructor is the following:


~this()
{
if (_p !is null)
{
destroy(_p);
_p = null;
}
}

Because _p is a pointer, destroy(_p) will not dereference and 
destroy what it points to. I think this is a bug with Unique. I 
think it should do


  destroy(*_p);


Now filed:
https://issues.dlang.org/show_bug.cgi?id=23561

Do you think it's OK to just fix this or do we need to do some 
kind of deprecation?


Re: pointer escaping return scope bug?

2022-11-27 Thread Nick Treleaven via Digitalmars-d-learn

On Friday, 25 November 2022 at 15:03:57 UTC, ShadoLight wrote:
I don't grok how `lf` can survive the local scope. Or am I 
missing something?


Perhaps because the local scope is not pushed as a separate 
(anonymous) function on the stack... if true then, yes, then 
`lf` will indeed have the same physical lifetime as main (and 
`p`)...?


On the other hand, if you add a destructor to `LockedFile`, it 
will be invoked at the end of the local scope, not the end of 
main.


Yes, the actual code does have a destructor. It's analogous to 
this:


```d
@safe:

struct S
{
private int* fps;

auto fp() return scope => fps;

this(int)
{
fps = new int;
}

@disable this();
@disable void opAssign(S);

~this() @trusted // how do we make this safe?
{
import core.memory;
GC.free(fps);
}
}

void main()
{
int* p;
{
auto lf = S(5);
p = lf.fp;
}
assert(p != null); // address escaped
}
```

That compiles with -dip1000. D doesn't seem to have a way to 
prevent the memory outliving the struct.


Just to note there is another problem when the struct is 
destroyed explicitly whilst the `fp` result is still live. But 
that could be solved by making `object.destroy` and 
`std.algorithm.move` be restricted to @system for certain structs 
like this one (either opt-in or some other mechanism). The first 
problem doesn't seem to have a solution.


Re: pointer escaping return scope bug?

2022-11-25 Thread Tejas via Digitalmars-d-learn

On Friday, 25 November 2022 at 17:45:57 UTC, Paul Backus wrote:

On Friday, 25 November 2022 at 14:07:28 UTC, ShadoLight wrote:
On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus 
wrote:
Since, in your example, `lf` has global lifetime, the 
compiler deduces that `lf.fp` also has global lifetime, and 
therefore there is nothing wrong with assigning it to `p`.


I follow your rationale, but for the life of me I cannot see 
how `lf` _"has global lifetime"_.


You're right, my terminology here is sloppy. I'm really talking 
about the memory pointed to by `lf`, not `lf` itself, so I 
should really say that `lf` *points to memory* with global 
lifetime (or perhaps "`*lf` has global lifetime").


Time to use separation logic

# 


Re: pointer escaping return scope bug?

2022-11-25 Thread Paul Backus via Digitalmars-d-learn

On Friday, 25 November 2022 at 14:07:28 UTC, ShadoLight wrote:
On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus 
wrote:
Since, in your example, `lf` has global lifetime, the compiler 
deduces that `lf.fp` also has global lifetime, and therefore 
there is nothing wrong with assigning it to `p`.


I follow your rationale, but for the life of me I cannot see 
how `lf` _"has global lifetime"_.


You're right, my terminology here is sloppy. I'm really talking 
about the memory pointed to by `lf`, not `lf` itself, so I should 
really say that `lf` *points to memory* with global lifetime (or 
perhaps "`*lf` has global lifetime").


Re: pointer escaping return scope bug?

2022-11-25 Thread ShadoLight via Digitalmars-d-learn

On Friday, 25 November 2022 at 14:07:28 UTC, ShadoLight wrote:

On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```

[snip]


I don't grok how `lf` can survive the local scope. Or am I 
missing something?


Perhaps because the local scope is not pushed as a separate 
(anonymous) function on the stack... if true then, yes, then `lf` 
will indeed have the same physical lifetime as main (and `p`)...?


On the other hand, if you add a destructor to `LockedFile`, it 
will be invoked at the end of the local scope, not the end of 
main.


I find it a bit confusing what the term "lifetime" should pertain 
to in the case of variables declared inside a local scope inside 
a function - destructor invocation or physical existence of the 
variable on the stack?


But this has no bearing on the heap allocation and the lifetime 
of `p` in the example.




Re: pointer escaping return scope bug?

2022-11-25 Thread ShadoLight via Digitalmars-d-learn

On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus wrote:
On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven 
wrote:

Hi,
The following seems like a bug to me (reduced code, FILE* 
changed to int*):

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```
There's no error with -dip1000.
I'll file this unless I overlooked something.


I think this is intended behavior, because you *do* get an 
error if you replace `new int` with a pointer to a stack 
variable; e.g.,


int local;
auto lf = LockedFile();

The `return scope` qualifier on the method does *not* mean "the 
return value of this method is `scope`". It means "this method 
may return one of this object's pointers, but does not allow 
them to escape anywhere else." In other words, it lets the 
compiler determine that the return value of `lf.fp` has *the 
same* lifetime as `lf` itself.


Since, in your example, `lf` has global lifetime, the compiler 
deduces that `lf.fp` also has global lifetime, and therefore 
there is nothing wrong with assigning it to `p`.


I follow your rationale, but for the life of me I cannot see how 
`lf` _"has global lifetime"_.


Looks to me like `lf` is a value instance of the `LockedFile` 
struct (so on the stack) in a local scope inside main. I fully 
agree that the above code is not problematic, but isn't that 
because `p` is declared outside this local scope, and the 
allocation that happens inside the local scope (in the `lf` 
constructor) is on the heap, so the allocation (now assigned to 
`p`) survives the end of the local scope (and the end of the life 
of `lf`) since it is `p` that has global lifetime?


I don't grok how `lf` can survive the local scope. Or am I 
missing something?






Re: pointer escaping return scope bug?

2022-11-19 Thread Dukc via Digitalmars-d-learn
On Saturday, 19 November 2022 at 15:02:54 UTC, Nick Treleaven 
wrote:

On Saturday, 19 November 2022 at 14:52:23 UTC, ag0aep6g wrote:
That's essentially just a function that returns its pointer 
parameter. So the program boils down to this:


```D
@safe:
int* fp(return scope int* p) { return p; }
void main()
{
int* p;
{
auto lf = new int;
p = fp(lf);
}
assert(p != null); // address escaped
}
```

Which is fine, as far as I can tell. `lf` is not `scope`. And 
when you pass it through `fp`, the result is still not 
`scope`. So escaping it is allowed.


You do get an error when you make `lf` `scope` (explicitly or 
implicitly). So everything seems to be in order.


OK, so how do I make `lf` implicitly scope?


Have the `int*` inside it to point to a local, or assign another 
`scope int*` to it.




Re: pointer escaping return scope bug?

2022-11-19 Thread ag0aep6g via Digitalmars-d-learn
On Saturday, 19 November 2022 at 15:02:54 UTC, Nick Treleaven 
wrote:

OK, so how do I make `lf` implicitly scope?


By explicit/implicit I just meant this:


scope explicit = new int;
int x;
auto implicit = 


That's probably not helping with whatever you want to accomplish.


Re: pointer escaping return scope bug?

2022-11-19 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 19 November 2022 at 14:52:23 UTC, ag0aep6g wrote:
That's essentially just a function that returns its pointer 
parameter. So the program boils down to this:



@safe:
int* fp(return scope int* p) { return p; }
void main()
{
int* p;
{
auto lf = new int;
p = fp(lf);
}
assert(p != null); // address escaped
}


Which is fine, as far as I can tell. `lf` is not `scope`. And 
when you pass it through `fp`, the result is still not `scope`. 
So escaping it is allowed.


You do get an error when you make `lf` `scope` (explicitly or 
implicitly). So everything seems to be in order.


OK, so how do I make `lf` implicitly scope?


Re: pointer escaping return scope bug?

2022-11-19 Thread Paul Backus via Digitalmars-d-learn
On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven 
wrote:

Hi,
The following seems like a bug to me (reduced code, FILE* 
changed to int*):

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```
There's no error with -dip1000.
I'll file this unless I overlooked something.


I think this is intended behavior, because you *do* get an error 
if you replace `new int` with a pointer to a stack variable; e.g.,


int local;
auto lf = LockedFile();

The `return scope` qualifier on the method does *not* mean "the 
return value of this method is `scope`". It means "this method 
may return one of this object's pointers, but does not allow them 
to escape anywhere else." In other words, it lets the compiler 
determine that the return value of `lf.fp` has *the same* 
lifetime as `lf` itself.


Since, in your example, `lf` has global lifetime, the compiler 
deduces that `lf.fp` also has global lifetime, and therefore 
there is nothing wrong with assigning it to `p`.


Re: pointer escaping return scope bug?

2022-11-19 Thread ag0aep6g via Digitalmars-d-learn

On 19.11.22 15:07, Nick Treleaven wrote:

Hi,
The following seems like a bug to me (reduced code, FILE* changed to int*):
```d
@safe:

struct LockedFile
{
     private int* fps;

     auto fp() return scope => fps;
}

void main()
{
     int* p;
     {
     auto lf = LockedFile(new int);
     p = lf.fp;
     }
     assert(p != null); // address escaped
}
```
There's no error with -dip1000.
I'll file this unless I overlooked something.


Let me rewrite `fp` as a static method. It's easier (for me) to 
understand what's going on that way:



static int* fp(return scope ref LockedFile that)
{
return that.fps;
}


That's essentially just a function that returns its pointer parameter. 
So the program boils down to this:



@safe:
int* fp(return scope int* p) { return p; }
void main()
{
int* p;
{
auto lf = new int;
p = fp(lf);
}
assert(p != null); // address escaped
}


Which is fine, as far as I can tell. `lf` is not `scope`. And when you 
pass it through `fp`, the result is still not `scope`. So escaping it is 
allowed.


You do get an error when you make `lf` `scope` (explicitly or 
implicitly). So everything seems to be in order.


pointer escaping return scope bug?

2022-11-19 Thread Nick Treleaven via Digitalmars-d-learn

Hi,
The following seems like a bug to me (reduced code, FILE* changed 
to int*):

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```
There's no error with -dip1000.
I'll file this unless I overlooked something.


Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread Imperatorn via Digitalmars-d-learn

On Tuesday, 1 November 2022 at 19:49:47 UTC, mw wrote:
On Tuesday, 1 November 2022 at 18:18:45 UTC, Steven 
Schveighoffer wrote:



[...]


Maybe the hunt library author doesn't know. (My code does not 
directly use this library, it got pulled in by some other 
decencies.)


[...]


Please, if you see anything in the docs that needs to be updated, 
make a PR right away <3


Documentation saves lives!

The times I have thought "I'll do it later" have been too many.


Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tuesday, 1 November 2022 at 18:18:45 UTC, Steven Schveighoffer 
wrote:


Oh yeah, isDaemon detaches the thread from the GC. Don't do 
that unless you know what you are doing.


As discussed on discord, this isn't actually true. All it does is 
prevent the thread from being joined before exiting the runtime.


What is *likely* happening is, the runtime shuts down. That 
thread is still running, but the D runtime is gone. So it 
eventually starts trying to do something (like let's say, access 
thread local storage), and it's gone. Hence the segfault.


-Steve


Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread mw via Digitalmars-d-learn
On Tuesday, 1 November 2022 at 18:18:45 UTC, Steven Schveighoffer 
wrote:




And I just noticed, one of the thread trace points to here:

https://github.com/huntlabs/hunt/blob/master/source/hunt/util/DateTime.d#L430

```
class DateTime {
   shared static this() {
     ...
     dateThread.isDaemon = true;  // not sure if this is 
related

   }
}
```

in the comments, it said: "BUG: ... crashed".  Looks like 
someone run into this (cleanup) issue already, but unable to 
fix it.


Anyway I logged an issue there:

https://github.com/huntlabs/hunt/issues/96




Oh yeah, isDaemon detaches the thread from the GC. Don't do 
that unless you know what you are doing.




Maybe the hunt library author doesn't know. (My code does not 
directly use this library, it got pulled in by some other 
decencies.)



Currently, the `isDaemon` doc does not mention this about this:

https://dlang.org/library/core/thread/threadbase/thread_base.is_daemon.html

Sets the daemon status for this thread. While the runtime will 
wait for all normal threads to complete before tearing down the 
process, daemon threads are effectively ignored and thus will not 
prevent the process from terminating. In effect, daemon threads 
will be terminated automatically by the OS when the process exits.


Maybe we should add to the doc?


BTW, what is exactly going wrong with their code?

I saw the tick() method call inside the anonymous `dateThread` is 
accessing these two stack variables of shared static this():


https://github.com/huntlabs/hunt/blob/master/source/hunt/util/DateTime.d#L409

Appender!(char[])[2] bufs;
const(char)[][2] targets;

Why does this tick() call work after the static this() finished 
in a normal run?


Why the problem only shows up when program finish?




Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread Steven Schveighoffer via Digitalmars-d-learn
On Tuesday, 1 November 2022 at 18:18:45 UTC, Steven Schveighoffer 
wrote:


Oh yeah, isDaemon detaches the thread from the GC. Don't do 
that unless you know what you are doing.


As discussed on discord, this isn't true actually. All it does is 
prevent the thread from being joined before exiting the runtime.


What is *likely* happening is, the runtime shuts down. That 
thread is still running, but the D runtime is gone. So it 
eventually starts trying to do something (like let's say, access 
thread local storage), and it's gone. Hence the segfault.


-Steve


Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/1/22 1:47 PM, mw wrote:

Can you show a code snippet that includes the parallel foreach?


(It's just a very straight forward foreach on an array; as I said it may 
not be relevant.)



And I just noticed, one of the thread trace points to here:

https://github.com/huntlabs/hunt/blob/master/source/hunt/util/DateTime.d#L430

```
class DateTime {
   shared static this() {
     ...
     dateThread.isDaemon = true;  // not sure if this is related
   }
}
```

in the comments, it said: "BUG: ... crashed".  Looks like someone run 
into this (cleanup) issue already, but unable to fix it.


Anyway I logged an issue there:

https://github.com/huntlabs/hunt/issues/96




Oh yeah, isDaemon detaches the thread from the GC. Don't do that unless 
you know what you are doing.


-Steve


Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread mw via Digitalmars-d-learn

Can you show a code snippet that includes the parallel foreach?


(It's just a very straight forward foreach on an array; as I said 
it may not be relevant.)



And I just noticed, one of the thread trace points to here:

https://github.com/huntlabs/hunt/blob/master/source/hunt/util/DateTime.d#L430

```
class DateTime {
  shared static this() {
...
dateThread.isDaemon = true;  // not sure if this is related
  }
}
```

in the comments, it said: "BUG: ... crashed".  Looks like someone 
run into this (cleanup) issue already, but unable to fix it.


Anyway I logged an issue there:

https://github.com/huntlabs/hunt/issues/96




Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Nov 01, 2022 at 10:37:57AM -0700, Ali Çehreli via Digitalmars-d-learn 
wrote:
> On 11/1/22 10:27, H. S. Teoh wrote:
> 
> > Maybe try running Digger to reduce the code for you?
> 
> Did you mean dustmite, which is accessible as 'dub dustmite
> ' but I haven't used it.

Oh yes, sorry, I meant dustmite, not digger. :-P


> My guess for the segmentation fault is that the OP is executing
> destructor code that assumes some members are alive. If so, the code
> should be moved from destructors to functions to be called like
> obj.close(). But it's just a guess...
[...]

Yes, that's a common gotcha.


T

-- 
We are in class, we are supposed to be learning, we have a teacher... Is it too 
much that I expect him to teach me??? -- RL


Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread Ali Çehreli via Digitalmars-d-learn

On 11/1/22 10:27, H. S. Teoh wrote:

> Maybe try running Digger to reduce the code for you?

Did you mean dustmite, which is accessible as 'dub dustmite 
' but I haven't used it.


My guess for the segmentation fault is that the OP is executing 
destructor code that assumes some members are alive. If so, the code 
should be moved from destructors to functions to be called like 
obj.close(). But it's just a guess...


Ali



Re: druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Nov 01, 2022 at 05:19:56PM +, mw via Digitalmars-d-learn wrote:
> My program received signal SIGSEGV, Segmentation fault.
> 
> Its simplified structure looks like this:
> 
> ```
> void foo() {
>   ...
>   writeln("done");  // saw this got printed!
> }
> 
> int main() {
>   foo();
>   return 0;
> }
> 
> ```

Can you show a code snippet that includes the parallel foreach?  Because
the above code snippet is over-simplified to the point it's impossible
to tell what the original problem might be, since obviously calling a
function that calls writeln would not crash the program.

Maybe try running Digger to reduce the code for you?


T

-- 
Never step over a puddle, always step around it. Chances are that whatever made 
it is still dripping.


druntime thread (from foreach parallel?) cleanup bug

2022-11-01 Thread mw via Digitalmars-d-learn

My program received signal SIGSEGV, Segmentation fault.

Its simplified structure looks like this:

```
void foo() {
  ...
  writeln("done");  // saw this got printed!
}

int main() {
  foo();
  return 0;
}

```

So, just before the program exit, it failed. I suspect druntime 
has a thread (maybe due to foreach parallel) cleanup bug 
somewhere, which is unrelated to my own code. This kind of bug is 
hard to re-produce, not sure if I should file an issue.


I'm using: LDC - the LLVM D compiler (1.30.0) on x86_64.


Under gdb, here is the threads info (for the record):

Thread 11 "xxx" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x153df700 (LWP 36258)]
__GI___res_iclose (free_addr=true, statp=0x153dfdb8) at 
res-close.c:103

103 res-close.c: No such file or directory.


(gdb) info threads
  Id   Target Id Frame
  1Thread 0x15515000 (LWP 36244) "lt" 0x10af1d2d 
in __GI___pthread_timedjoin_ex (threadid=23456246527744, 
thread_return=0x0, abstime=0x0, block=) at 
pthread_join_common.c:89
* 11   Thread 0x153df700 (LWP 36258) "lt" __GI___res_iclose 
(free_addr=true, statp=0x153dfdb8) at res-close.c:103
  17   Thread 0x155544817700 (LWP 36264) "lt" 0x10afac70 
in __GI___nanosleep (requested_time=0x155544810e90, 
remaining=0x155544810ea8) at 
../sysdeps/unix/sysv/linux/nanosleep.c:28



(gdb) thread 1
[Switching to thread 1 (Thread 0x15515000 (LWP 36244))]
#0  0x10af1d2d in __GI___pthread_timedjoin_ex 
(threadid=23456246527744, thread_return=0x0, abstime=0x0, 
block=) at pthread_join_common.c:89

89  pthread_join_common.c: No such file or directory.
(gdb) where
#0  0x10af1d2d in __GI___pthread_timedjoin_ex 
(threadid=23456246527744, thread_return=0x0, abstime=0x0, 
block=) at pthread_join_common.c:89
#1  0x55fb94f8 in 
core.thread.osthread.joinLowLevelThread(ulong) ()
#2  0x55fd7210 in 
_D4core8internal2gc4impl12conservativeQw3Gcx15stopScanThreadsMFNbZv ()
#3  0x55fd3ae7 in 
_D4core8internal2gc4impl12conservativeQw3Gcx4DtorMFZv ()
#4  0x55fd3962 in 
_D4core8internal2gc4impl12conservativeQw14ConservativeGC6__dtorMFZv ()

#5  0x55fc2ce7 in rt_finalize2 ()
#6  0x55fc0056 in rt_term ()
#7  0x55fc0471 in 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv ()

#8  0x55fc0356 in _d_run_main2 ()
#9  0x55fc01ae in _d_run_main ()
#10 0x55840c02 in main (argc=2, argv=0x7fffe188) at 
//home/zhou/project/ldc2-1.30.0-linux-x86_64/bin/../import/core/internal/entrypoint.d:42
#11 0x10163b97 in __libc_start_main (main=0x55840be0 
, argc=2, argv=0x7fffe188, init=, 
fini=, rtld_fini=, 
stack_end=0x7fffe178)

at ../csu/libc-start.c:310
#12 0x556dccca in _start ()


(gdb) thread 11
[Switching to thread 11 (Thread 0x153df700 (LWP 36258))]
#0  __GI___res_iclose (free_addr=true, statp=0x153dfdb8) at 
res-close.c:103

103 res-close.c: No such file or directory.
(gdb) where
#0  __GI___res_iclose (free_addr=true, statp=0x153dfdb8) at 
res-close.c:103

#1  res_thread_freeres () at res-close.c:138
#2  0x102de8c2 in __libc_thread_freeres () at 
thread-freeres.c:29
#3  0x10af0700 in start_thread (arg=0x153df700) at 
pthread_create.c:476
#4  0x10263a3f in clone () at 
../sysdeps/unix/sysv/linux/x86_64/clone.S:95



(gdb) thread 17
[Switching to thread 17 (Thread 0x155544817700 (LWP 36264))]
#0  0x10afac70 in __GI___nanosleep 
(requested_time=0x155544810e90, remaining=0x155544810ea8) at 
../sysdeps/unix/sysv/linux/nanosleep.c:28
28  ../sysdeps/unix/sysv/linux/nanosleep.c: No such file or 
directory.

(gdb) where
#0  0x10afac70 in __GI___nanosleep 
(requested_time=0x155544810e90, remaining=0x155544810ea8) at 
../sysdeps/unix/sysv/linux/nanosleep.c:28
#1  0x55fb8c3b in 
_D4core6thread8osthread6Thread5sleepFNbNiSQBo4time8DurationZv ()
#2  0x55d9a0c2 in 
_D4hunt4util8DateTimeQj25_sharedStaticCtor_L406_C5FZ9__lambda4MFZv () at home/zhou/.dub/packages/hunt-1.7.16/hunt/source/hunt/util/DateTime.d:430

#3  0x55fb89f4 in thread_entryPoint ()
#4  0x10af06db in start_thread (arg=0x155544817700) at 
pthread_create.c:463
#5  0x10263a3f in clone () at 
../sysdeps/unix/sysv/linux/x86_64/clone.S:95





Re: Is this a new bug ?

2022-09-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On Saturday, 24 September 2022 at 06:13:55 UTC, test123 wrote:
If so please report it for me to bugs platform. I can not 
register one.



```d
package {
version(TEST) {
static:
} else {
   __gshared:
}
uint  test = 0;
}
```


ldmd2  -betterC -vtls -c ./test.d

./test.d(7): `test` is thread local


static does nothing to module level variables.

Without attributes, test will be thread local. Your attributes 
are having no effect on the variable because they don’t apply 
outside the braces.


-Steve



Re: Is this a new bug ?

2022-09-24 Thread Adam D Ruppe via Digitalmars-d-learn

On Saturday, 24 September 2022 at 06:13:55 UTC, test123 wrote:

If so please report it for me to bugs platform.


This isn't a bug, the effect of keyword: things stop at the 
matching }.


(static if and version don't introduce a namespace scope, but 
they still follow this rule for the { colon: ... } blocks)


You need to duplicate your uint test2 variable inside those 
branches.


Re: Is this a new bug ?

2022-09-24 Thread test123 via Digitalmars-d-learn
On Saturday, 24 September 2022 at 07:11:12 UTC, rikki cattermole 
wrote:

```d
version(all) {
__gshared:
uint test2;
}

uint test;
```

Output with -vtls:

```
Up to  2.079.1: Success with output: onlineapp.d(9): test 
is thread local
Since  2.080.1: Success with output: onlineapp.d(9): `test` 
is thread local

```

Looks fine to me.


I think it should not be thread local.


Re: Is this a new bug ?

2022-09-24 Thread rikki cattermole via Digitalmars-d-learn

```d
version(all) {
__gshared:
uint test2;
}

uint test;
```

Output with -vtls:

```
Up to  2.079.1: Success with output: onlineapp.d(9): test is thread 
local
Since  2.080.1: Success with output: onlineapp.d(9): `test` is 
thread local

```

Looks fine to me.



Is this a new bug ?

2022-09-24 Thread test123 via Digitalmars-d-learn
If so please report it for me to bugs platform. I can not 
register one.



```d
package {
version(TEST) {
static:
} else {
   __gshared:
}
uint  test = 0;
}
```


ldmd2  -betterC -vtls -c ./test.d

./test.d(7): `test` is thread local


Re: How to workaround on this (bug?)

2022-09-23 Thread Kagamin via Digitalmars-d-learn

Provide two functions and let the caller choose
```
void fun(ref Variant v) nothrow
{
}

void fun2(Variant v)
{
fun(v);
}
```


Re: How to workaround on this (bug?)

2022-09-23 Thread Quirin Schroll via Digitalmars-d-learn

On Friday, 16 September 2022 at 22:43:43 UTC, frame wrote:

```d
import std.variant;

// error: destructor `std.variant.VariantN!32LU.VariantN.~this` 
is not `nothrow`

void fun(Variant v) nothrow
{

}

void main()
{
   fun(Variant());
}
```

A reference, pointer or slice works. I could do something on 
the caller site but the signature of `fun()` should remain like 
above.


A reference effectively is a never-`null` pointer. A slice is a 
pointer to the first of many objects plus the number of those 
objects (or empty, or `null`).
It boils down to pointers, and the pointed-to `Variant` object is 
not the responsibility of `fun`.


When you have a parameter that binds by copy, you cannot escape 
from calling its destructor, and if one happens not to be 
`nothrow`, your function cannot be `nothrow`.


The new semantics for `in` (compile with `-preview=in`) might 
work for you. The `in` storage class binds by copy if the copy is 
cheap – which I suspect is never the case for a `Variant` – or 
else by reference; and it can bind temporaries by reference 
(unlike `ref`). However, `in` also incurs `const` and `scope`. It 
is unlikely that `scope` will be your problem, but `const` very 
well might be an issue when the contained value has indirections  
to mutable values, e.g. an `int[]` will be read as a 
`const(int)[]`.


Calling the destructor is then the responsibility of the caller.

```d
// Compile with -preview=in

import std.variant;

void fun(in Variant v) nothrow { }

void main()
{
fun(Variant()); // okay: `in` binds rvalues
Variant v;
fun(v); // okay: `in` binds lvalues
}
```


Re: How to workaround on this (bug?)

2022-09-16 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Sep 17, 2022 at 12:19:16AM +, frame via Digitalmars-d-learn wrote:
> On Friday, 16 September 2022 at 23:06:35 UTC, H. S. Teoh wrote:
> 
> > Basically, if you pass something to .fun by value, then that value
> > must be destroyed by .fun once it's ready to return.  So if the
> > value has a dtor, the dtor must be called upon exiting from .fun.
> > Since Variant has a throwing dtor, this means .fun may throw when
> > it's about to return, which violates `nothrow`.
> 
> I understand why this happens but not why the compiler does not check
> if the value is actually destroyed in user code by `.destroy()`.
[...]

I don't know for sure, but my guess is that .destroy is seen by the
compiler just like any other D function; i.e., it's not treated
specially. So it would not factor into the compiler's lifetime
considerations.

Or are you talking about the case where the Variant may not actually
contain values that have dtors?  That information is not available until
runtime; the compiler can't make decisions based on that.


T

-- 
Political correctness: socially-sanctioned hypocrisy.


Re: How to workaround on this (bug?)

2022-09-16 Thread frame via Digitalmars-d-learn

On Friday, 16 September 2022 at 23:06:35 UTC, H. S. Teoh wrote:

Basically, if you pass something to .fun by value, then that 
value must be destroyed by .fun once it's ready to return.  So 
if the value has a dtor, the dtor must be called upon exiting 
from .fun.  Since Variant has a throwing dtor, this means .fun 
may throw when it's about to return, which violates `nothrow`.


I understand why this happens but not why the compiler does not 
check if the value is actually destroyed in user code by 
`.destroy()`.


Thanks for your suggestion, I will consider this.


Re: How to workaround on this (bug?)

2022-09-16 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Sep 16, 2022 at 10:43:43PM +, frame via Digitalmars-d-learn wrote:
> ```d
> import std.variant;
> 
> // error: destructor `std.variant.VariantN!32LU.VariantN.~this` is not
> `nothrow`
> void fun(Variant v) nothrow
> {
> 
> }
> 
> void main()
> {
>fun(Variant());
> }
> ```
> 
> A reference, pointer or slice works.

Yes, because in that case the dtor would not need to be invoked in .fun.


> I could do something on the caller site but the signature of `fun()`
> should remain like above.

I was doing to suggest using `const ref`, but if the signature must
remain the same, then I'm out of ideas.

Basically, if you pass something to .fun by value, then that value must
be destroyed by .fun once it's ready to return.  So if the value has a
dtor, the dtor must be called upon exiting from .fun.  Since Variant has
a throwing dtor, this means .fun may throw when it's about to return,
which violates `nothrow`.


T

-- 
If creativity is stifled by rigid discipline, then it is not true creativity.


How to workaround on this (bug?)

2022-09-16 Thread frame via Digitalmars-d-learn

```d
import std.variant;

// error: destructor `std.variant.VariantN!32LU.VariantN.~this` 
is not `nothrow`

void fun(Variant v) nothrow
{

}

void main()
{
   fun(Variant());
}
```

A reference, pointer or slice works. I could do something on the 
caller site but the signature of `fun()` should remain like above.


Re: can not take const struct member address at CTFE , is this a bug?

2022-09-15 Thread test123 via Digitalmars-d-learn

On Thursday, 15 September 2022 at 11:33:43 UTC, Dennis wrote:

On Thursday, 15 September 2022 at 04:13:56 UTC, test123 wrote:

I hope we have github bugs.


It's being worked on.


glad to know we are move into github.

Please help me create a bug report if who has free time and 
bugs account.


Here you go: https://issues.dlang.org/show_bug.cgi?id=23336


thanks for the help.


Re: can not take const struct member address at CTFE , is this a bug?

2022-09-15 Thread Dennis via Digitalmars-d-learn

On Thursday, 15 September 2022 at 04:13:56 UTC, test123 wrote:

I hope we have github bugs.


It's being worked on.

Please help me create a bug report if who has free time and 
bugs account.


Here you go: https://issues.dlang.org/show_bug.cgi?id=23336


Re: can not take const struct member address at CTFE , is this a bug?

2022-09-14 Thread test123 via Digitalmars-d-learn
On Wednesday, 14 September 2022 at 14:41:38 UTC, Steven 
Schveighoffer wrote:

On 9/14/22 12:53 AM, test123 wrote:
On Wednesday, 14 September 2022 at 00:40:38 UTC, Ruby The 
Roobster wrote:
The addresses of items stored in memory are by definition not 
constant.  This isn't a bug.


If so why this can work ?

```d
struct c { uint a, b;}
__gshared const c d = { 3, 4};
__gshared const e = & d;
```

the `e` can get address of `d`, then it should be to get 
address of `d.a`


Yes, this looks like a bug. Please report if not reported 
already.


-Steve


Thanks for explain.

Some how I can not create account for d Bugs,  I hope we have use 
github bugs.



Please help me create a bug report if who has free time and bugs 
account.





Re: can not take const struct member address at CTFE , is this a bug?

2022-09-14 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/14/22 12:53 AM, test123 wrote:

On Wednesday, 14 September 2022 at 00:40:38 UTC, Ruby The Roobster wrote:
The addresses of items stored in memory are by definition not 
constant.  This isn't a bug.


If so why this can work ?

```d
struct c { uint a, b;}
__gshared const c d = { 3, 4};
__gshared const e = & d;
```

the `e` can get address of `d`, then it should be to get address of `d.a`


Yes, this looks like a bug. Please report if not reported already.

-Steve


Re: can not take const struct member address at CTFE , is this a bug?

2022-09-13 Thread test123 via Digitalmars-d-learn
On Wednesday, 14 September 2022 at 00:40:38 UTC, Ruby The 
Roobster wrote:
The addresses of items stored in memory are by definition not 
constant.  This isn't a bug.


If so why this can work ?

```d
struct c { uint a, b;}
__gshared const c d = { 3, 4};
__gshared const e = & d;
```

the `e` can get address of `d`, then it should be to get address 
of `d.a`


Re: can not take const struct member address at CTFE , is this a bug?

2022-09-13 Thread Ruby The Roobster via Digitalmars-d-learn

On Tuesday, 13 September 2022 at 11:16:55 UTC, test123 wrote:

```d
struct c { uint a, b;}
__gshared const c d = { 3, 4};
__gshared const e = 
```

./test.d(4): Error: expression `(3u, 4u).a` is not a constant


I need this to work around C struct array member like this:

```c
struct c {
 uint32_t a, b;
 uint32_t[] arr;
}
```

If I can take const object member address as __gshared const, 
then the problem is fixed.



Or if I can force cast the const object pointer into other 
type, will work be able to work this around. (but not work)


```sh
Error: reinterpreting cast from 
`const(validate_KnownRegex_enum_init_type)*` to 
`const(upb_MiniTable_Enum)*` is not supported in CTFE

```


The addresses of items stored in memory are by definition not 
constant.  This isn't a bug.


can not take const struct member address at CTFE , is this a bug?

2022-09-13 Thread test123 via Digitalmars-d-learn

```d
struct c { uint a, b;}
__gshared const c d = { 3, 4};
__gshared const e = 
```

./test.d(4): Error: expression `(3u, 4u).a` is not a constant


I need this to work around C struct array member like this:

```c
struct c {
 uint32_t a, b;
 uint32_t[] arr;
}
```

If I can take const object member address as __gshared const, 
then the problem is fixed.



Or if I can force cast the const object pointer into other type, 
will work be able to work this around. (but not work)


```sh
Error: reinterpreting cast from 
`const(validate_KnownRegex_enum_init_type)*` to 
`const(upb_MiniTable_Enum)*` is not supported in CTFE

```





Re: mixin template bug with opBinary?

2022-07-22 Thread Paul Backus via Digitalmars-d-learn

On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote:

I get:
```
foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B 
b) pure nothrow @nogc @safe => a])` does not match template 
declaration `opBi(A, A function(A, A)[string] f0)`

```

Is this a bug or am I doing something wrong?


Looks like this bug:

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


Re: mixin template bug with opBinary?

2022-07-22 Thread Anthony Quizon via Digitalmars-d-learn

On Friday, 22 July 2022 at 12:56:44 UTC, Adam D Ruppe wrote:

```
mixin template opBi(
alias f0
) {
static foreach (k, f; f0) { typeof(this) opBinary(string op:
k)(typeof(this) r) { return f(this, r); } }
}
```


Thanks, this seems to do the trick.


Re: mixin template bug with opBinary?

2022-07-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/22/22 8:33 AM, Anthony Quizon wrote:

Hello,

I'm trying to create a mixin for quick binary operator overloads by 
passing in types with a corresponding associative array of strings to 
functions. However,

the code I currently have:

```
module foo;

mixin template opBi(
     A, A function(A, A)[string] f0,
) {
     static foreach (k, f; f0) { A opBinary(string op: k)(A r) { return 
f(this, r); } }

}

struct A {
     mixin opBi!(
     A, [ "+": (A a, A b) => a],
     );
}

struct B {
     mixin opBi!(
     B, [ "+": (B a, B b) => a],
     );
}


```

Will not let me override operators on both struct A and B.

I get:
```
foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B b) pure 
nothrow @nogc @safe => a])` does not match template declaration `opBi(A, 
A function(A, A)[string] f0)`

```

Is this a bug or am I doing something wrong?


It's typing the AA differently, and therefore it doesn't fit. The type 
of the AA you are passing in is `T1[string]`, where it's expecting 
`T2[string]`, where:


`T1` is `B function(B, B) pure nothrow @nogc @safe`
`T2` is `B function(B, B)`

I don't know if there's a better way to do this, other than use a 
further template parameter to match the function type passed in.


-Steve


Re: mixin template bug with opBinary?

2022-07-22 Thread Adam D Ruppe via Digitalmars-d-learn

On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote:

Is this a bug or am I doing something wrong?


I think this is a bug. The compiler must not take well to this 
pattern, maybe the assoc array template argument, but idk. It 
looks like the first type used gets cached and reused even if it 
is supposed to change.


I vaguely recall seeing this before but yeah smells buggy 
anyway.



An alternative you might consider is dropping some of the type 
and using typeof(this):


```
module foo;

mixin template opBi(
alias f0
) {
static foreach (k, f; f0) { typeof(this) opBinary(string op:
k)(typeof(this) r) { return f(this, r); } }
}

struct A {
mixin opBi!(
[ "+": (A a, A b) => a],
);
}

struct B {
mixin opBi!(
[ "+": (B a, B b) => a],
);
}
```

That sidesteps the bug though it just trusts you pass the right 
type to `f0`.


  1   2   3   4   5   6   7   8   9   10   >