Re: What is the meaning of @future ?

2021-09-17 Thread Meta via Digitalmars-d-learn

On Friday, 17 September 2021 at 10:31:34 UTC, bauss wrote:

On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote:

Hello D community.

I was browsing the `__traits` keywords and I found `isFuture` 
whose descriptions says something about `@future`-annotated 
variables.


[link](https://dlang.org/spec/traits.html#isFuture)

I didn't find anything about `@future` for the D programming 
language. I only found that this annotation is used in Apex to 
denote futures (a.k.a. promises) as programming concept.


Is this something which exists, existed, was abandoned early 
as an idea? I remember I had read that D uses a "fiber" 
library to provide coroutines and such.


Maybe somebody knows an answer for this.


It's just another "useless" attribute that the language has 
added before fixing any of the real problems :)


Basically it reserves a symbol for the future.

It's similar to creating ex. an empty function that throws an 
error or something like "Not implemented"


While I understand why it was added and what purpose it serves 
then I fail to see why that  was prioritized over actual issues.


It's solving an almost non-existing issue.


I think the main reason it was added is because Sociomantic asked 
for it, but they are of course not around anymore.


Re: GC seems to crash my C-code function

2021-09-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/17/21 2:27 AM, frame wrote:

On Thursday, 16 September 2021 at 18:02:44 UTC, Steven Schveighoffer wrote:

Are you sure? Be very pedantic about what C functions do with the data 
you send it. Sometimes they store it somewhere to use later. Sometimes 
they expect it to be allocated by the C heap, etc.


Without seeing how you use it, I can't tell you if it's wrong or not.


If you want to have a look the original C-library is here
https://github.com/rdoeffinger/iec16022

I'm only using the encoder function iec16022ecc200f.


Looking at that signature, it does not appear that it uses 
zero-termination at all, as it takes a length. So using `dup` and 
therefore the gc is totally unnecessary.


I'm assuming that string is the barcode argument?

What does your call look like?





If it's a literal, you don't need to toStringz (which also allocates). 
All string literals are zero-terminated (and actually implicitly 
castable to `immutable char *`).




Thanks, I'm just careful with casting.
Does it really allocate from a literal if it's used on the stack only? 
Is `-vgc` switch reliable?


The `-vgc` switch appears to only identify allocations that the compiler 
invokes via hooks, not ones that other functions invoke (or ones that 
are direct calls into the GC).


In other words, it helps you find your direct allocations using the 
compiler, not ones that are buried in already-compiled code.


Try this with `-vgc`, and it reports nothing:

```d
import core.memory;
void main()
{
   auto x = GC.malloc(10);
}
```

This makes sense, as it may not have the function code to analyze, and 
it also cannot infer GC allocation from a lack of @nogc (a non-@nogc 
function *may* allocate, but does not *necessarily* allocate). It also 
would be quite useless to see some function buried inside druntime that 
allocates, not knowing what the call stack was.


The docs for `-vgc` should really be updated to clarify. It currently 
just says "List all gc allocations including hidden ones".


-Steve


Re: yet another segfault - array out of bound is not caught by try catch

2021-09-17 Thread jfondren via Digitalmars-d-learn

On Friday, 17 September 2021 at 11:10:33 UTC, seany wrote:
Compile with `dub build --compiler=ldc2 `. this should enable 
array bound checking options.


By default, yes. run `dub -v build --compiler=ldc2` to see the 
exact commands that dub runs.



But should it not be caught by range error ?


Based on what you've said, yes it should.


If I do `print l`in gdb, i find :
$1 = {length = 0, ptr = 0x0}
With `print l[0]` i get: `Attempt to take address of value not 
located in memory.`.


i.e., a segfault. null (or 0x0 (or 0)) isn't part of the memory 
addresses your program is allowed to access, so memory protection 
prevents the attempt to access it.



What absolute rookie mistake am I committing?


From this it doesn't sound like you are committing one, but if 
you're wanting bounds checking to be a normal part of program 
logic, and not something that only ever happens due to a 
programmer's error, then I think you're cutting against the grain 
of the language, where


- bounds checking is easily removed from all but @safe functions 
with normal flags


- flags exist to remove it from @safe functions also

- the *Error family of exceptions, including RangeError are not 
intended to be catchable


- raising and immediately catching an exception like this is 
slower and more verbose than an explicit test.


Rather than returning an empty array on an error and expecting a 
caller to catch RangeError, you could throw a normal exception on 
error, and then you have tools like `std.exception.ifThrown` to 
make dealing with that exception nicer.


Re: How can we view source code that has been generated (say via "static foreach") ?

2021-09-17 Thread Dennis via Digitalmars-d-learn
On Wednesday, 15 September 2021 at 19:59:43 UTC, james.p.leblanc 
wrote:

However, with various combinations of templates, UDAs, and
mixins it has not been easy.


Apart from -mixin, there's also the undocumented -vcg-ast switch 
that prints the AST before code generation, showing instantiated 
templates and unrolled static foreach loops.




Re: How can we view source code that has been generated (say via "static foreach") ?

2021-09-17 Thread Nicholas Wilson via Digitalmars-d-learn
On Thursday, 16 September 2021 at 04:54:21 UTC, james.p.leblanc 
wrote:
Thank you for your kind response.  Wow, at first the large 
output file
from a small test program was a bit surprising .., but actually 
it is

manageable to dig through to find the interesting bits.

So, this is quite useful!  Thanks again, now I am off to do 
some digging...


Best Regards,
James


Note that that will only give the expansions from string mixins, 
not from template mixins, templates and other things.




Re: yet another segfault - array out of bound is not caught by try catch

2021-09-17 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 17 September 2021 at 11:10:33 UTC, seany wrote:

I have now this function, as a private member in a Class :
} catch (RangeError er) {


I can't remember if you can catch an index OOB error but try 
`catch (Throwable er)` will work if it is catchable at all and 
you can figure out what kind of Error you have by printing its 
name.


 "Attempt to take address of value not located in memory" ? I 
am not even calling / accessing a pointer. I am trying to 
extract a value outside an array bound.


`Type[]` arrays in D are effectively struct {size_t length; Type* 
ptr; } under the hood. Your problem is the array has no elements 
which is why trying to extract a value outside an array bound is 
an irrecoverable error.


with the bound checking operation in place, would the bound 
error be triggered before the attempt to take unavailable 
address error has a chance to trigger?


with a null array of zero length `arr`, `arr[0]` with bounds 
check enabled will fail the bounds check before it tries to 
dereference the pointer. if you try `arr.ptr[0]` to bypass the 
bounds checking (which is a very bad idea!) you will then try to 
load from an invalid memory address and crash.




yet another segfault - array out of bound is not caught by try catch

2021-09-17 Thread seany via Digitalmars-d-learn

I have now this function, as a private member in a Class :


double calculate_lineLength( int i)  {
field.rawData [] * rd;   // ignore 
the details, this works;
rd = cast (field.rawData [] *)  dataSet; // ignore 
the details, this works;


auto l = this.allLines[i];   // this is 
defined as
 // int [][] 
allLines =
 //   
 new int [][] (0,0)
 // in case 
of failure, this is empty

double r = 0;
try {
writeln("l ", l);// prints []
writeln("i ", i);// prints i, 
in this case, i is set to 0

writeln(l.length);   // prints 0
writeln("l0 ", l[0]);// segfault 
- i want it to be caught

write("will print");
writeln("rd", (*rd));
write("will not print...");
auto p0 = (*rd)[l[0]];
auto p1 = (*rd)[l[1]];
	r = calculate_geoDistance_vincenty(p0.lat,p1.lat, 
p0.lon, p1.lon);

} catch (RangeError er) {
writeln("range error");
}
return r;
}


Compile with `dub build --compiler=ldc2 `. this should enable 
array bound checking options.



I am debugging with gdb :

`gdb ./myprogram`

Then, in gdb console :

`run arg1 arg2 `

Result is :

91753
91754
91755
91756
[New Thread 0x77560640 (LWP 45344)]
[New Thread 0x7fffe640 (LWP 45345)]
[New Thread 0x76d5f640 (LWP 45346)]
[New Thread 0x7655e640 (LWP 45347)]
[New Thread 0x75d5d640 (LWP 45348)]
[New Thread 0x7555c640 (LWP 45349)]
[New Thread 0x74d5b640 (LWP 45350)]
[New Thread 0x7fffef7fe640 (LWP 45351)]
[New Thread 0x7fffeeffd640 (LWP 45352)]
[New Thread 0x7fffee7fc640 (LWP 45353)]
[New Thread 0x7fffedffb640 (LWP 45354)]
[New Thread 0x7fffed7fa640 (LWP 45355)]
[New Thread 0x7fffecff9640 (LWP 45356)]
[New Thread 0x7fffb640 (LWP 45357)]
[New Thread 0x7fffbf7fe640 (LWP 45358)]
[New Thread 0x7fffbeffd640 (LWP 45359)]
[New Thread 0x7fffbe7fc640 (LWP 45360)]
[New Thread 0x7fffbdffb640 (LWP 45361)]
[New Thread 0x7fffbd7fa640 (LWP 45362)]
getting LINES done
alllines: []
l []
i 0
0
Thread 1 "myprogram" received signal SIGSEGV, 
Segmentation fault.
_D14analysisEngine9geoEngine20calculate_lineLengthMFiZd 
(this=, i=0) at source/analysisEngine.d:15526

15526
writeln("l0 ", l[0]);

So, to see what is going on, i use the command `bt`:


#0  
_D14analysisEngine9geoEngine20calculate_lineLengthMFiZd 
(this=, i=0) at source/analysisEngine.d:15526
#1  0x555dba40 in 
_D14analysisEngine9geoEngine13add_turnLinesMFZv (this=out>) at source/analysisEngine.d:7387
#2  0x555e375a in 
_D14analysisEngine9geoEngine15analyze_tillageMFZv 
(this=0x7756a000) at source/analysisEngine.d:5329
#3  0x5560d082 in _Dmain (args=...) at 
source/AI.d:123



Okey, I know where to look for : it's the line asking for 
`writeln("l0 ", l[0]);`.



But should it not be caught by range error ? If I do `print 
l`in gdb, i find :

$1 = {length = 0, ptr = 0x0}

With `print l[0]` i get: `Attempt to take address of value not 
located in memory.`. I believe the array printing syntax is 
valid; see 
[here](https://phoenix.goucher.edu/~kelliher/cs23/gdb.html).


What absolute rookie mistake am I committing? What does it mean : 
"Attempt to take address of value not located in memory" ? I am 
not even calling / accessing a pointer. I am trying to extract a 
value outside an array bound.


I imagine they all have their addresses. But with the bound 
checking operation in place, would the bound error be triggered 
before the attempt to take unavailable address error has a chance 
to trigger?


Thank you.




Re: What is the meaning of @future ?

2021-09-17 Thread bauss via Digitalmars-d-learn

On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote:

Hello D community.

I was browsing the `__traits` keywords and I found `isFuture` 
whose descriptions says something about `@future`-annotated 
variables.


[link](https://dlang.org/spec/traits.html#isFuture)

I didn't find anything about `@future` for the D programming 
language. I only found that this annotation is used in Apex to 
denote futures (a.k.a. promises) as programming concept.


Is this something which exists, existed, was abandoned early as 
an idea? I remember I had read that D uses a "fiber" library to 
provide coroutines and such.


Maybe somebody knows an answer for this.


It's just another "useless" attribute that the language has added 
before fixing any of the real problems :)


Basically it reserves a symbol for the future.

It's similar to creating ex. an empty function that throws an 
error or something like "Not implemented"


While I understand why it was added and what purpose it serves 
then I fail to see why that  was prioritized over actual issues.


It's solving an almost non-existing issue.


Re: Is this a compiler aliasing bug?

2021-09-17 Thread bauss via Digitalmars-d-learn

On Friday, 17 September 2021 at 09:44:53 UTC, Chris Katko wrote:
I'm debugging some code I wrote back in 2017 and a bounding box 
collision detection kept giving spurious answers till I 
resorted to assuming nothing and dumped every variable and 
alias.


I kept getting results like it was checking against itself, and 
of course, that would result in finding a collision. So I threw 
an assert in to check if it was identical objects (as in an 
error outside this function), and it didn't fire off. It 
appears (unless my eyes are deceiving me?) that variable 
aliases themselves are broken.


$ dmd --version
DMD64 D Compiler v2.098.0-beta.2

code:

```d
class drawable_object_t obj;

bool is_colliding_with(drawable_object_t obj) //was a class 
member

{
assert(this != obj);  //does not fire off

alias x1 = x;
alias y1 = y;
alias w1 = w;
alias h1 = h;

alias x2 = obj.x;
alias y2 = obj.y;
alias w2 = obj.w;
alias h2 = obj.h;

writeln("x1: ", x1, " y1: ", y1, " w1: ", w1, " h1: ", h1);
writeln("x2: ", x2, " y2: ", y2, " w2: ", w2, " h2: ", h2);

writeln("x1: ", x, " y1: ", y, " w1: ", w, " h1: ", h);
	writeln("x2: ", obj.x, " y2: ", obj.y, " w2: ", obj.w, " h2: 
", obj.h);

}
/*
output:

x1: 50 y1: 81 w1: 5 h1: 6
x2: 50 y2: 81 w2: 5 h2: 6   <
x1: 50 y1: 81 w1: 5 h1: 6
x2: 200 y2: 86.54 w2: 26 h2: 16 <
*/
```

The arrows point to the dependency. The top two sets of numbers 
should _not_ be identical.


It's not a bug because "obj.x" referes to the same symbol that is 
"this.x"


Alias will create an alias for a symbol, not an expression or the 
like.


So

obj.x is the same as this.x and in that case the alias will refer 
to the same thing.


The problem here is that the function is local to the class, so 
the alias will always refer to the class members directly and not 
the passed instance.


You really shouldn't use alias like this anyway and should just 
use auto, if it's because you want to save typing.


It shouldn't have any impact at all tbh.


Re: Is this a compiler aliasing bug?

2021-09-17 Thread ag0aep6g via Digitalmars-d-learn

On 17.09.21 11:44, Chris Katko wrote:

bool is_colliding_with(drawable_object_t obj) //was a class member
 {

[...]

 alias x2 = obj.x;
 alias y2 = obj.y;
 alias w2 = obj.w;
 alias h2 = obj.h;

[...]

     }


Those aliases don't work like you want them to. You can't have an alias 
to an object's field. What you get is an alias to the symbol in the 
class. I.e., you get this:


alias x2 = typeof(obj).x;

And when you use that in a method, it becomes `this.x`. `obj` is 
completely forgotten.


I my opinion, `alias x2 = obj.x` should be an error, but I'm not sure if 
it's considered a bug.


Is this a compiler aliasing bug?

2021-09-17 Thread Chris Katko via Digitalmars-d-learn
I'm debugging some code I wrote back in 2017 and a bounding box 
collision detection kept giving spurious answers till I resorted 
to assuming nothing and dumped every variable and alias.


I kept getting results like it was checking against itself, and 
of course, that would result in finding a collision. So I threw 
an assert in to check if it was identical objects (as in an error 
outside this function), and it didn't fire off. It appears 
(unless my eyes are deceiving me?) that variable aliases 
themselves are broken.


$ dmd --version
DMD64 D Compiler v2.098.0-beta.2

code:

```d
class drawable_object_t obj;

bool is_colliding_with(drawable_object_t obj) //was a class member
{
assert(this != obj);  //does not fire off

alias x1 = x;
alias y1 = y;
alias w1 = w;
alias h1 = h;

alias x2 = obj.x;
alias y2 = obj.y;
alias w2 = obj.w;
alias h2 = obj.h;

writeln("x1: ", x1, " y1: ", y1, " w1: ", w1, " h1: ", h1);
writeln("x2: ", x2, " y2: ", y2, " w2: ", w2, " h2: ", h2);

writeln("x1: ", x, " y1: ", y, " w1: ", w, " h1: ", h);
	writeln("x2: ", obj.x, " y2: ", obj.y, " w2: ", obj.w, " h2: ", 
obj.h);

}
/*
output:

x1: 50 y1: 81 w1: 5 h1: 6
x2: 50 y2: 81 w2: 5 h2: 6   <
x1: 50 y1: 81 w1: 5 h1: 6
x2: 200 y2: 86.54 w2: 26 h2: 16 <
*/
```

The arrows point to the dependency. The top two sets of numbers 
should _not_ be identical.


Re: GC seems to crash my C-code function

2021-09-17 Thread frame via Digitalmars-d-learn

On Friday, 17 September 2021 at 06:58:01 UTC, jfondren wrote:

On Friday, 17 September 2021 at 06:27:40 UTC, frame wrote:

Thanks, I'm just careful with casting.
Does it really allocate from a literal if it's used on the 
stack only? Is `-vgc` switch reliable?


looks to me like it calls

...

Interesting analysis, thanks for your effort!


Re: GC seems to crash my C-code function

2021-09-17 Thread jfondren via Digitalmars-d-learn

On Friday, 17 September 2021 at 06:27:40 UTC, frame wrote:

Thanks, I'm just careful with casting.
Does it really allocate from a literal if it's used on the 
stack only? Is `-vgc` switch reliable?


looks to me like it calls

```d
// object
private U[] _dup(T, U)(scope T[] a) pure nothrow @trusted if 
(__traits(isPOD, T))

{
if (__ctfe)
return _dupCtfe!(T, U)(a);

import core.stdc.string : memcpy;
auto arr = _d_newarrayU(typeid(T[]), a.length);
memcpy(arr.ptr, cast(const(void)*) a.ptr, T.sizeof * 
a.length);

return *cast(U[]*) &arr;
}
```

->

```d
// rt.lifetime
extern (C) void[] _d_newarrayU(const scope TypeInfo ti, size_t 
length) pure nothrow @weak

{
...
auto info = __arrayAlloc(size, ti, tinext);
...
}
```

->

```d
// rt.lifetime
BlkInfo __arrayAlloc(size_t arrsize, const scope TypeInfo ti, 
const TypeInfo tinext) nothrow pure

{
...
auto bi = GC.qalloc(padded_size, attr, tinext);
...
}
```

->

```d
// gc.impl.conservative.gc
BlkInfo qalloc( size_t size, uint bits, const TypeInfo ti) 
nothrow

{

if (!size)
{
return BlkInfo.init;
}

BlkInfo retval;

retval.base = runLocked!(mallocNoSync, mallocTime, 
numMallocs)(size, bits, retval.size, ti);


if (!(bits & BlkAttr.NO_SCAN))
{
memset(retval.base + size, 0, retval.size - size);
}

retval.attr = bits;
return retval;
}
```

which you can also follow in an objdump. Conclusion: -vgc is 
missing this GC allocation.


To stack-allocate a mutable copy of a string literal go with

```d
@safe @nogc nothrow unittest {
enum S = "hello world";
char[S.length+1] s1 = S;
char* s2 = &s1[0];

// Normally you'd expect s1.ptr[s1.length] here,
// but the '\0' byte is explicitly part of s1 due to length+1 
above.

assert(s1[s1.length-1] == '\0');

(() @trusted {
import core.stdc.stdio : puts;
import std.string : fromStringz;

puts(s2);
assert(s2.fromStringz == S);
})();
}
```