Re: Unintentional sharing?

2024-06-06 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jun 06, 2024 at 05:49:39PM +, Andy Valencia via Digitalmars-d-learn 
wrote:
> I was using instance initialization which allocated a new object.  My
> intention was this initialization would happen per-instance, but all
> instances appear to share the same sub-object?  That is, f1.b and f2.b
> appear to point to a single object?
[...]

Yes, if you want a per-instance object, you need to do it in this(), not
in the initializer.


--T


Re: Unintentional sharing?

2024-06-06 Thread Nick Treleaven via Digitalmars-d-learn

On Thursday, 6 June 2024 at 17:49:39 UTC, Andy Valencia wrote:
I was using instance initialization which allocated a new 
object.  My intention was this initialization would happen 
per-instance, but all instances appear to share the same 
sub-object?  That is, f1.b and f2.b appear to point to a single 
object?  Obviously I moved the new into the initializer code, 
but I hadn't appreciated how initial instance values were 
calculated once.  Interestingly, this makes it similar to how 
Python calculates default argument values for functions.


class Bar {
int z = 3;
}

class Foo {
auto b = new Bar();
}

void
main() {
import std.stdio : writeln;

auto f1 = new Foo(), f2 = new Foo();
f1.b.z = 0;
writeln(f2.b.z);
}


This is a long standing issue:
https://issues.dlang.org/show_bug.cgi?id=2947

I think with the next edition we can disallow (tail) mutable 
initializers for fields (and TLS globals too).


Re: Unintentional sharing?

2024-06-06 Thread evilrat via Digitalmars-d-learn

On Thursday, 6 June 2024 at 17:49:39 UTC, Andy Valencia wrote:
I was using instance initialization which allocated a new 
object.  My intention was this initialization would happen 
per-instance, but all instances appear to share the same 
sub-object?  That is, f1.b and f2.b appear to point to a single 
object?  Obviously I moved the new into the initializer code, 
but I hadn't appreciated how initial instance values were 
calculated once.  Interestingly, this makes it similar to how 
Python calculates default argument values for functions.


class Bar {
int z = 3;
}

class Foo {
auto b = new Bar();
}

void
main() {
import std.stdio : writeln;

auto f1 = new Foo(), f2 = new Foo();
f1.b.z = 0;
writeln(f2.b.z);
}


What you are seeing here is indeed sharing reference.
It happens because type initializer sets fields after memory 
allocation but before constructor call, and so since it is using 
value known at compile time all instances will have share same 
reference.


https://dlang.org/spec/class.html#constructors


Unintentional sharing?

2024-06-06 Thread Andy Valencia via Digitalmars-d-learn
I was using instance initialization which allocated a new object. 
 My intention was this initialization would happen per-instance, 
but all instances appear to share the same sub-object?  That is, 
f1.b and f2.b appear to point to a single object?  Obviously I 
moved the new into the initializer code, but I hadn't appreciated 
how initial instance values were calculated once.  Interestingly, 
this makes it similar to how Python calculates default argument 
values for functions.


class Bar {
int z = 3;
}

class Foo {
auto b = new Bar();
}

void
main() {
import std.stdio : writeln;

auto f1 = new Foo(), f2 = new Foo();
f1.b.z = 0;
writeln(f2.b.z);
}


Re: How to pass in reference a fixed array in parameter

2024-06-06 Thread Quirin Schroll via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote:
I am currently trying to learn how to program in D. I thought 
that I could start by trying some maze generation algorithms. I 
have a maze stored as 2D array of structure defined as follow 
which keep tracks of wall positions:


~~~
struct s_cell
{
   bool north = true;
   bool east = true;
   bool south = true;
   bool west = true;
}
~~~

I try to create a 2D array of fixed length and pass it in 
parameter as a reference. Normally, in C, I would have used a 
pointer as parameter, and pass the address of the array. Here, 
I thought it would have been easier just to pass a slice of the 
array, since a slice is a reference to the original array. So I 
wrote the signature like this:


~~~
void main()
{  writeln("Maze generation demo");

   s_cell [5][5] maze;
   print_maze (maze);

}

void print_maze ( s_cell [][] maze )
{
}
~~~

My idea is that print_maze use a slice of what ever is sent in 
parameter. Unfortunately, I get the following error message:


~~~
Error: function `mprmaze.print_maze(s_cell[][] maze)` is not 
callable using argument types `(s_cell[5][5])`
  cannot pass argument `maze` of type `s_cell[5][5]` to 
parameter `s_cell[][] maze`

~~~

I tried to find a solution on the internet, but could not find 
anything, I stumble a lot on threads about Go or Rust language 
even if I specify "d language" in my search.


Else is there other ways to pass an array as reference using 
parameter modifiers like: ref,in,out ...


Else, can it be done the C way using pointers?

Thank you.


First things first, put `@safe:` on the top of the file or put 
`@safe` at the end of every function declarator. It makes 
anything that could be undefined behavior an error:

```d
void main() @safe
{
writeln("Maze generation demo");

s_cell [5][5] maze;
print_maze (maze);

}

// change to: ( const ref s_cell [5][5] maze )
void print_maze ( s_cell [][] maze ) @safe
{
}
```

A `T[]` is a pointer–length pair, aka. a slice. A `T[n]` is a 
block of `n` values of type `T`. Assuming you know a thing or two 
about C, a `T[n]` converts to a `T[]` like an `int` converts to a 
`long`: It’s lossless and safe, but not pointer compatible.


For the same reason an `int*` can’t convert to a `long*`, a 
`T[m][n]` can’t convert to a `T[][]`.


Also, if you’re new, be aware some people call slices “dynamic 
arrays,” which is really misleading sometimes.


* If a function writes a maze, pass the maze by `ref`. Note that 
`ref` is not part of the parameter’s type (as in C++), but a 
property of the parameter akin to its type.
* If a function only reads a maze, pass the maze by `const ref`; 
or `in` using the command-line option `-preview=in` which: allows 
rvalues and doesn’t bind by reference if the object bound is 
small and trivial to copy.


Re: bool passed by ref, safe or not ?

2024-06-06 Thread Quirin Schroll via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 18:31:12 UTC, Basile B. wrote:

On Wednesday, 5 June 2024 at 01:18:06 UTC, Paul Backus wrote:

On Tuesday, 4 June 2024 at 16:58:50 UTC, Basile B. wrote:

```d
void main(string[] args)
{
ushort a = 0b;
bool* b = cast(bool*)
setIt(*b);
assert(a == 0b); // what actually happens
assert(a == 0b1110); // what would be safe
}
```


[...]


Do I corrupt memory here or not ?
Is that a safety violation ?


`cast(bool*)` is a safety violation.

The only [safe values][1] for a `bool` are 0 (false) and 1 
(true). By creating a `bool*` that points to a different 
value, you have violated the language's safety invariants. 
Because of this, operations that would normally be safe 
(reading or writing through the `bool*`) may now result in 
undefined behavior.


[1]: https://dlang.org/spec/function.html#safe-values


Obviously the topic was created because of the recent move D 
made. Sorry for the "catchy" aspect BTW. Now I remember that D 
safety is unrelated to undefined behaviors.


I don’t think there’s any meaningful difference. If a program has 
UB, it can do anything, including corrupt memory. If a program 
corrupts memory, that’s UB. `@safe` means UB-free, which includes 
free of memory corruption.


Re: How to pass in reference a fixed array in parameter

2024-06-06 Thread Eric P626 via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 10:36:50 UTC, Nick Treleaven wrote:

```d
import std.stdio;
alias s_cell = int;

void main()
{  writeln("Maze generation demo");

   s_cell [5][5] maze;
   int n;
   foreach (i, row; maze)
foreach (j, col; row)
maze[i][j] = n++;

   s_cell[][5] slices;
   foreach (i, _; maze)
   slices[i] = maze[i];

   print_maze (slices);
}

void print_maze ( s_cell [][] maze )
{
foreach (a; maze)
a.writeln();
}
```


Thanks for the feedback

Almost all my projects works intensively with multiple dimensions 
arrays. So I want to know the best way to manage multi 
dimensional arrays. I guess the best solution so far are:


1) Only use dynamic arrays.
2) Use a single dimension array, and compute the index value from 
x,y,z coordinates (Makes dynamic allocation easier). This 
solution could work well with pointers too.
3) Make my own data structure or class containing the array. 
Allowing to pass the structure/class by reference. Could allow 
encapsulating single or multi dimensional arrays.


About .ptr, the documentation page state that:

~~~
The .ptr property for static and dynamic arrays will give the 
address of the first element in the array:

~~~

So I assumed that the following expressions where equivalent, but 
I guess the multiple dimensions do complicate things:


~~~
array.ptr ==  == [0]
~~~

So ommitting the "ref" keyword it's like if the data was read 
only even if the variable is not passed by value. That means that 
this signature cannot modify the content of the 2D array:


~~~
void print_maze ( s_cell [][] maze )
~~~

For the create_maze() function, I would need to use the follwing 
signature since it changes the content of the array.


~~~
void print_maze ( ref s_cell [][] maze )
~~~

I imagine `a.writeln();` is the same as `writeln(a);` ?

Your foreach loops look better than mine. Here is the code I have 
been using to print the maze.


~~~
void print_maze ( s_cell [][] maze )
{
   //print top row, assume full
   foreach ( cell; maze[0] ) write("+---");
   writeln("+");
   for ( int y = 0; y < maze.length; y++)
   {  //print content
  write("|"); //assume edge is always full
  for ( int x = 0; x < maze[y].length; x++)
  {  write("   ");
 write( maze[y][x].east ? "|": " ");
  }
  writeln();
  foreach ( cell; maze[y] ) write( cell.south ? "+---" : "
" );

  writeln("+");
   }
}
~~~

your iteration version is more neat:

~~~
foreach (i, row; maze)
foreach (j, col; row)
maze[i][j] = n++;
~~~

I like that using 2 variables (i,row) or (j,col) allow to access 
the variable later as a element in a collection or as an index. 
It's more flexible. I'll guess I'll need to read more code to 
avoid programming too much old school (^_^).




Re: bool passed by ref, safe or not ?

2024-06-05 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 01:18:06 UTC, Paul Backus wrote:

On Tuesday, 4 June 2024 at 16:58:50 UTC, Basile B. wrote:

```d
void main(string[] args)
{
ushort a = 0b;
bool* b = cast(bool*)
setIt(*b);
assert(a == 0b); // what actually happens
assert(a == 0b1110); // what would be safe
}
```


[...]


Do I corrupt memory here or not ?
Is that a safety violation ?


`cast(bool*)` is a safety violation.

The only [safe values][1] for a `bool` are 0 (false) and 1 
(true). By creating a `bool*` that points to a different value, 
you have violated the language's safety invariants. Because of 
this, operations that would normally be safe (reading or 
writing through the `bool*`) may now result in undefined 
behavior.


[1]: https://dlang.org/spec/function.html#safe-values


Obviously the topic was created because of the recent move D 
made. Sorry for the "catchy" aspect BTW. Now I remember that D 
safety is unrelated to undefined behaviors.


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread bauss via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 06:22:34 UTC, Eric P626 wrote:


I tried the following signatures with the ref keyword and it 
did not change anything:


~~~
void print_maze ( ref s_cell maze )
void print_maze ( ref s_cell [][] maze )
~~~

From what I found, arrays passed in parameters are always 
passed by reference. So the ref keyword seems pointless.




There is one useful functionality about the ref keyword when 
passing arrays, it is that you can change the original array 
reference to another array reference.


Ex.

```
void foo(ref int[] x)
{
x = [1,2,3];
}

void bar(int[] y)
{
y = [1,2,3];
}

void main()
{
auto x = [0,0,0];
auto y = [1,1,1];

foo(x);
bar(y);

writeln(x);
writeln(y);
}
```

The output of the program is:

```
[1, 2, 3]
[1, 1, 1]
```

Of course in your case this doesn't matter, but just wanted to 
point out that adding ref to array parameters actually pose a 
function.


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread evilrat via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 11:27:32 UTC, Nick Treleaven wrote:

On Wednesday, 5 June 2024 at 09:24:23 UTC, evilrat wrote:
for simple cases like this it might work, but 2d array is not 
even contiguous,


A 2D static array is contiguous:
https://dlang.org/spec/arrays.html#rectangular-arrays

D static arrays, while using the same syntax, are implemented 
as a fixed rectangular layout in a contiguous block of memory


Yeah ok, i might have messed up with columns last time, but it 
works.


```d
int[5][5] test;

foreach(i; 0..5) {
foreach(j; 0..5) {
test[i][j] = i * 5 + j;
}
}

foreach(i; 0..25) {
assert(test[0].ptr[i] == i);
}
```


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 09:24:23 UTC, evilrat wrote:
for simple cases like this it might work, but 2d array is not 
even contiguous,


A 2D static array is contiguous:
https://dlang.org/spec/arrays.html#rectangular-arrays

D static arrays, while using the same syntax, are implemented 
as a fixed rectangular layout in a contiguous block of memory


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 10:27:47 UTC, Nick Treleaven wrote:

   foreach (i, row; maze)
   slices[i] = row;


Sorry that assignment was wrong (edited at last minute). Fixed:

```d
import std.stdio;
alias s_cell = int;

void main()
{  writeln("Maze generation demo");

   s_cell [5][5] maze;
   int n;
   foreach (i, row; maze)
foreach (j, col; row)
maze[i][j] = n++;

   s_cell[][5] slices;
   foreach (i, _; maze)
   slices[i] = maze[i];

   print_maze (slices);
}

void print_maze ( s_cell [][] maze )
{
foreach (a; maze)
a.writeln();
}
```


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 10:27:47 UTC, Nick Treleaven wrote:

//~ void print_maze ( s_cell [][] maze... )


I meant to delete that line!


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread Nick Treleaven via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote:

~~~
void main()
{  writeln("Maze generation demo");

   s_cell [5][5] maze;
   print_maze (maze);

}

void print_maze ( s_cell [][] maze )
{
}
~~~


This is how to do it without GC allocations (I have used `int` 
instead for demo purposes):


```d
import std.stdio;
alias s_cell = int;

void main()
{  writeln("Maze generation demo");

   s_cell [5][5] maze = [0, 1, 2, 3, 4];
   s_cell[][5] slices; // static array of 5 slices
   foreach (i, row; maze)
   slices[i] = row;

   print_maze (slices);
}

//~ void print_maze ( s_cell [][] maze... )
void print_maze ( s_cell [][] maze )
{
foreach (a; maze)
a.writeln();
}
```


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread Kagamin via Digitalmars-d-learn

With accessor:
```
void main()
{
s_cell[] maze=make(5,5);
s_cell a=maze.get(1,2);
print_maze(maze);
}

void print_maze(s_cell[] maze)
{
}

s_cell[] make(int width, int height)
{
return new s_cell[width*height];
}

s_cell get(s_cell[] maze, int x, int y)
{
return maze[5*y+x]; //oops
}
```
looks like you need to store the maze width somewhere.


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 06:22:34 UTC, Eric P626 wrote:
Now according to the book, it's possible to assign a slice from 
a fixed array. This code will compile:


~~~
int[12] monthDays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 
30, 31 ];

int[] a_slice = monthDays;
~~~


The element types are both int, so the compiler can slice the 
static array. As if you had written `a_slice = monthDays[];`.


How come the assignment does not work when passing a parameter. 
I tried the following and it failed:


~~~
s_cell [5][5] maze;


The element type is s_cell[5].


s_cell [][] sliced_maze = maze;


The element type of sliced_maze is s_cell[], so the element types 
are incompatible.



~~~
void print_maze ( ref s_cell maze )
void print_maze ( ref s_cell [][] maze )
~~~

From what I found, arrays passed in parameters are always 
passed by reference. So the ref keyword seems pointless.


You don't need `ref` to be able to read the array length and 
elements.
However, if you want to modify the array length, and have it 
affect the caller's dynamic array, you need `ref`.




---

The only solution left is to use pointers. But even this does 
not seems to work as in C. I created a function with different 
pointer signature and they all fails.


Normally in C, this would have worked:

~~~
s_cell [5][5] maze;
create_maze();


Pass `[0][0]` instead.


~~~
Error: function `mprmaze.create_maze(s_cell[][]* maze)` is not 
callable using argument types `(s_cell[5][5]*)`
cannot pass argument `& maze` of type `s_cell[5][5]*` to 
parameter `s_cell[][]* maze`

~~~


s_cell[5][5] cannot implicitly convert to s_cell[][].

Now I think it expect a 2D array of pointers instead of a 
pointer on a 2D array.


It's also not clear if there is a difference between those 2 
notations:


~~~

maze.ptr
~~~


 is a pointer to s_cell[5][5].
maze.ptr is a pointer to s_cell[5]. `.ptr` means a pointer to the 
first element of the array.




Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread Kagamin via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote:
I try to create a 2D array of fixed length and pass it in 
parameter as a reference. Normally, in C, I would have used a 
pointer as parameter, and pass the address of the array.


Not obvious what you're trying to do. How would you do it in C? 
Use one dimensional array? You can use one dimensional array in D 
too. If dimensions of the maze are dynamic, you just write the 
maze creation function that allocates the maze as you want.


In simple case:

```
void main()
{  writeln("Maze generation demo");

s_cell [5][5] maze;
print_maze (maze);

}

void print_maze (ref s_cell [5][5] maze )
{
}
```

With factory:

```
void main()
{
s_cell[][] maze=make(5,5);
print_maze(maze);
}

void print_maze(s_cell[][] maze)
{
}

s_cell[][] make(int width, int height)
{
}
```


Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread evilrat via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 06:22:34 UTC, Eric P626 wrote:

On Tuesday, 4 June 2024 at 16:19:39 UTC, Andy Valencia wrote:

On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote:


Thanks for the comments. So far, I only managed to make it work 
by creating a dynamic array and keeping the same signature:


~~~
void main()
{  s_cell [][] maze = new s_cell[][](5,5);
   print_maze (maze);
}

void print_maze ( s_cell [][] maze )
{
}
~~~

Now according to the book, it's possible to assign a slice from 
a fixed array. This code will compile:


~~~
int[12] monthDays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 
30, 31 ];

int[] a_slice = monthDays;
~~~


for simple cases like this it might work, but 2d array is not 
even contiguous, simpler case like s_cell[5][] might work too.


How come the assignment does not work when passing a parameter. 
I tried the following and it failed:


~~~
s_cell [5][5] maze;
s_cell [][] sliced_maze = maze;
~~~

with this message:

~~~
Error: cannot implicitly convert expression `maze` of type 
`s_cell[5][5]` to `s_cell[][]`

~~~

Is it because it's a 2D array (slice of slice)? I need to 
manually copy each slice manually, or use a utility function to 
do the copy? This is why it cannot auto-magically do it with 
just when passing a parameter.




very likely this is the only solution - make a dynamic array by 
copying all elements.
there was few old bug tracker issues discussed wrt to static 
arrays and join function but there is seems to be no agreement so 
far.




~~~
Error: function `mprmaze.create_maze(s_cell[][]* maze)` is not 
callable using argument types `(s_cell[5][5]*)`
cannot pass argument `& maze` of type `s_cell[5][5]*` to 
parameter `s_cell[][]* maze`

~~~

Now I think it expect a 2D array of pointers instead of a 
pointer on a 2D array.


It's also not clear if there is a difference between those 2 
notations:


~~~

maze.ptr
~~~



there is, array itself is a tuple of length and pointer, the .ptr 
notation is just the data location, this is what you usually pass 
to C functions and not  itself.


to sum up, i wasn't able to make fixed-size arrays to work with 
dynamic arrays without making a copy, and I don't think this will 
change in the future because of various reasons including type 
system limitations and binary object formats.


so if you really absolutely need static arrays for example to 
avoid GC allocations in hot path than you need to make function 
that takes fixed size array.


in addition to that spec 
(https://dlang.org/spec/arrays.html#static-arrays) says static 
arrays is passed by value, unlike dynamic arrays that even when 
passed as length-and-pointer tuple will allow writing back to 
original data.





Re: bool passed by ref, safe or not ?

2024-06-05 Thread Nick Treleaven via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 09:09:40 UTC, Kagamin wrote:

On Wednesday, 5 June 2024 at 01:18:06 UTC, Paul Backus wrote:

The only safe values for a `bool` are 0 (false) and 1 (true).


AFAIK that was fixed and now full 8-bit range is safe.


`cast(bool) someByte` is fine - that doesn't reinterpret the bit 
representation.


The problem is certain values such as `0x2` for the byte 
representation can cause the boolean to be both true and false:

https://issues.dlang.org/show_bug.cgi?id=20148#c3

Void initialization of bool and bool union fields are now 
deprecated in @safe functions as of 2.109. There is a remaining 
case of casting an array to bool[], which I am working on 
disallowing in @safe.


Re: bool passed by ref, safe or not ?

2024-06-05 Thread Kagamin via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 01:18:06 UTC, Paul Backus wrote:

The only safe values for a `bool` are 0 (false) and 1 (true).


AFAIK that was fixed and now full 8-bit range is safe.


Re: bool passed by ref, safe or not ?

2024-06-05 Thread Dukc via Digitalmars-d-learn

Basile B. kirjoitti 4.6.2024 klo 19.58:
I understand that the notion of `bool` doesn't exist on X86, hence what 
will be used is rather an instruction that write on the lower 8 bits, 
but with a 7 bits corruption.


Do I corrupt memory here or not ?
Is that a safety violation ?
Viewing a valid boolean as an integer is still valid. Bit pattern of 
`false` is 0b_, and bit pattern of `true` is `0b_0001`. And 
even if the boolean is invalid, viewing it as an integer is probably 
valid if it was assigned to as an integer and not as an invalid boolean.


There's a related case though where the situation is unclear. How do 
`ubytes` other than 1 or 0, when viewed as bools? We probably can't say 
it's undefined behaviour, since it is allowed in `@safe`.


How I would define it, is that it's unspecific behaviour. That is if you 
have


```D
bool* unspecified = cast(bool*) new ubyte(0xff);
```

then

```
// same as void-initialising
bool a = *unspecified;
// also same as void-initialising
ubyte b = *unspecified;
// Reliably 0xff. It's using the memory slot as bool that makes it 
unspecified, but what's in the memory slot is not affected.

ubyte c = * cast(ubyte*) unspecified;

// Unspecified which happens. One and only one must happen though.
if (*unspecified) fun() else gun();

// Should this be required to call the same function as above? I'm not sure.
if (*unspecified) fun() else gun();
```




Re: How to pass in reference a fixed array in parameter

2024-06-05 Thread Eric P626 via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 16:19:39 UTC, Andy Valencia wrote:

On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote:

I tried to find a solution on the internet, but could not find 
anything, I stumble a lot on threads about Go or Rust language 
even if I specify "d language" in my search.


Aside from the excellent answer already present, I wanted to 
mention that searching with "dlang" has helped target my 
searches.


Welcome to D!  (From another newbie.)
Andy


Thanks for the comments. So far, I only managed to make it work 
by creating a dynamic array and keeping the same signature:


~~~
void main()
{  s_cell [][] maze = new s_cell[][](5,5);
   print_maze (maze);
}

void print_maze ( s_cell [][] maze )
{
}
~~~

Now according to the book, it's possible to assign a slice from a 
fixed array. This code will compile:


~~~
int[12] monthDays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 
31 ];

int[] a_slice = monthDays;
~~~

How come the assignment does not work when passing a parameter. I 
tried the following and it failed:


~~~
s_cell [5][5] maze;
s_cell [][] sliced_maze = maze;
~~~

with this message:

~~~
Error: cannot implicitly convert expression `maze` of type 
`s_cell[5][5]` to `s_cell[][]`

~~~

Is it because it's a 2D array (slice of slice)? I need to 
manually copy each slice manually, or use a utility function to 
do the copy? This is why it cannot auto-magically do it with just 
when passing a parameter.


I tried the following signatures with the ref keyword and it did 
not change anything:


~~~
void print_maze ( ref s_cell maze )
void print_maze ( ref s_cell [][] maze )
~~~

From what I found, arrays passed in parameters are always passed 
by reference. So the ref keyword seems pointless.


---

The only solution left is to use pointers. But even this does not 
seems to work as in C. I created a function with different 
pointer signature and they all fails.


Normally in C, this would have worked:

~~~
s_cell [5][5] maze;
create_maze();

void create_maze ( s_cell *maze)
{
}
~~~

I get the following error

~~~
Error: function `mprmaze.create_maze(s_cell* maze)` is not 
callable using argument types `(s_cell[5][5]*)`
cannot pass argument `& maze` of type `s_cell[5][5]*` to 
parameter `s_cell* maze`

~~~

But I get the idea of ambiguity, is the pointer pointing on a 
single cell, or an array of cells, so there might need a way to 
specify that it's not just an elements. I tried this:


~~~
s_cell [5][5] maze;
create_maze();

void create_maze ( s_cell [][]*maze)
{
}
~~~

and get this error

~~~
Error: function `mprmaze.create_maze(s_cell[][]* maze)` is not 
callable using argument types `(s_cell[5][5]*)`
cannot pass argument `& maze` of type `s_cell[5][5]*` to 
parameter `s_cell[][]* maze`

~~~

Now I think it expect a 2D array of pointers instead of a pointer 
on a 2D array.


It's also not clear if there is a difference between those 2 
notations:


~~~

maze.ptr
~~~

Do you have a code sample on how to pass a 2D array by pointer?

So far, the pointer solution seems like the only method that 
should be compatible with both fixed and dynamic arrays unless I 
am mistaken.


Re: bool passed by ref, safe or not ?

2024-06-04 Thread Olivier Pisano via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 05:15:42 UTC, Olivier Pisano wrote:


This is technically not a memory corruption, because as 
bool.sizeof < int.sizeof, you just write the low order byte of 
an int you allocated on the stack.


It was not an int, it was a ushort. Anyway, what I wrote still 
applies.


Re: bool passed by ref, safe or not ?

2024-06-04 Thread Olivier Pisano via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 16:58:50 UTC, Basile B. wrote:
question in the header, code in the body, execute on a X86 or 
X86_64 CPU



I understand that the notion of `bool` doesn't exist on X86, 
hence what will be used is rather an instruction that write on 
the lower 8 bits, but with a 7 bits corruption.


Do I corrupt memory here or not ?
Is that a safety violation ?



The problem is that while setIt() is @safe, your main function is 
not. So the pointer cast (which is not @safe) is permitted.


A bool is a 1 byte type with two possible values : false (0) and 
true (1).


When you set the value to false, you write 0 to the byte it 
points to.


This is technically not a memory corruption, because as 
bool.sizeof < int.sizeof, you just write the low order byte of an 
int you allocated on the stack.


Re: bool passed by ref, safe or not ?

2024-06-04 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 5 June 2024 at 01:18:06 UTC, Paul Backus wrote:

On Tuesday, 4 June 2024 at 16:58:50 UTC, Basile B. wrote:
you have violated the language's safety invariants.


ah mais non.



Re: bool passed by ref, safe or not ?

2024-06-04 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 16:58:50 UTC, Basile B. wrote:

```d
void main(string[] args)
{
ushort a = 0b;
bool* b = cast(bool*)
setIt(*b);
assert(a == 0b); // what actually happens
assert(a == 0b1110); // what would be safe
}
```


[...]


Do I corrupt memory here or not ?
Is that a safety violation ?


`cast(bool*)` is a safety violation.

The only [safe values][1] for a `bool` are 0 (false) and 1 
(true). By creating a `bool*` that points to a different value, 
you have violated the language's safety invariants. Because of 
this, operations that would normally be safe (reading or writing 
through the `bool*`) may now result in undefined behavior.


[1]: https://dlang.org/spec/function.html#safe-values


Re: bool passed by ref, safe or not ?

2024-06-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 16:58:50 UTC, Basile B. wrote:
question in the header, code in the body, execute on a X86 or 
X86_64 CPU


```d
module test;

void setIt(ref bool b) @safe
{
b = false;
}

void main(string[] args)
{
ushort a = 0b;
bool* b = cast(bool*)
setIt(*b);
assert(a == 0b); // what actually happens
assert(a == 0b1110); // what would be safe
}
```

I understand that the notion of `bool` doesn't exist on X86, 
hence what will be used is rather an instruction that write on 
the lower 8 bits, but with a 7 bits corruption.


Do I corrupt memory here or not ?


I don't think so. You passed an address to a bool, which uses 8 
bits of space, even though the compiler treats it as a 1-bit 
integer.


In order for your code to do what you expect, all bool writes 
would have to be read/modify/write operations. I don't think 
anyone would prefer this.



Is that a safety violation ?


No, you are not writing to memory you don't have access to. An 
address is pointing at a byte level, not a bit level.


-Steve


Re: bool passed by ref, safe or not ?

2024-06-04 Thread rkompass via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 16:58:50 UTC, Basile B. wrote:
question in the header, code in the body, execute on a X86 or 
X86_64 CPU


```d
module test;

void setIt(ref bool b) @safe
{
b = false;
}

void main(string[] args)
{
ushort a = 0b;
bool* b = cast(bool*)
setIt(*b);
assert(a == 0b); // what actually happens
assert(a == 0b1110); // what would be safe
}
```

I understand that the notion of `bool` doesn't exist on X86, 
hence what will be used is rather an instruction that write on 
the lower 8 bits, but with a 7 bits corruption.


Do I corrupt memory here or not ?
Is that a safety violation ?


No everything is fine.
The bool is the same size like byte or char.
So your cast makes  pointer to a byte.
And this byte has to be made completely zero by setIt, otherwise 
it would not be false in the sense of bool type.


bool passed by ref, safe or not ?

2024-06-04 Thread Basile B. via Digitalmars-d-learn
question in the header, code in the body, execute on a X86 or 
X86_64 CPU


```d
module test;

void setIt(ref bool b) @safe
{
b = false;
}

void main(string[] args)
{
ushort a = 0b;
bool* b = cast(bool*)
setIt(*b);
assert(a == 0b); // what actually happens
assert(a == 0b1110); // what would be safe
}
```

I understand that the notion of `bool` doesn't exist on X86, 
hence what will be used is rather an instruction that write on 
the lower 8 bits, but with a 7 bits corruption.


Do I corrupt memory here or not ?
Is that a safety violation ?


Re: How to pass in reference a fixed array in parameter

2024-06-04 Thread Andy Valencia via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote:

I tried to find a solution on the internet, but could not find 
anything, I stumble a lot on threads about Go or Rust language 
even if I specify "d language" in my search.


Aside from the excellent answer already present, I wanted to 
mention that searching with "dlang" has helped target my searches.


Welcome to D!  (From another newbie.)
Andy



Re: How to pass in reference a fixed array in parameter

2024-06-04 Thread evilrat via Digitalmars-d-learn

On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote:
I am currently trying to learn how to program in D. I thought 
that I could start by trying some maze generation algorithms. I 
have a maze stored as 2D array of structure defined as follow 
which keep tracks of wall positions:


~~~
struct s_cell
{
   bool north = true;
   bool east = true;
   bool south = true;
   bool west = true;
}
~~~

I try to create a 2D array of fixed length and pass it in 
parameter as a reference. Normally, in C, I would have used a 
pointer as parameter, and pass the address of the array. Here, 
I thought it would have been easier just to pass a slice of the 
array, since a slice is a reference to the original array. So I 
wrote the signature like this:


~~~
void main()
{  writeln("Maze generation demo");

   s_cell [5][5] maze;
   print_maze (maze);

}

void print_maze ( s_cell [][] maze )
{
}
~~~

My idea is that print_maze use a slice of what ever is sent in 
parameter. Unfortunately, I get the following error message:


~~~
Error: function `mprmaze.print_maze(s_cell[][] maze)` is not 
callable using argument types `(s_cell[5][5])`
  cannot pass argument `maze` of type `s_cell[5][5]` to 
parameter `s_cell[][] maze`

~~~

I tried to find a solution on the internet, but could not find 
anything, I stumble a lot on threads about Go or Rust language 
even if I specify "d language" in my search.


You have declared static array here, they cannot be implicitly 
converted to dynamic arrays.


It is not very obvious but it is a part of language design to 
avoid unnecessary GC allocations and for C compatibility reasons 
in some cases (e.g. strings known at compile implicitly has null 
appended to it to be able to pass pointer as is to C functions).


IIRC you can explicitly cast it to s_cell[][] to make it work but 
it will allocate new array when you append to it.


Else is there other ways to pass an array as reference using 
parameter modifiers like: ref,in,out ...


`ref` is exactly for that.


Else, can it be done the C way using pointers?


absolutely, even ref behind the scenes will basically do the same 
thing anyway.






How to pass in reference a fixed array in parameter

2024-06-04 Thread Eric P626 via Digitalmars-d-learn
I am currently trying to learn how to program in D. I thought 
that I could start by trying some maze generation algorithms. I 
have a maze stored as 2D array of structure defined as follow 
which keep tracks of wall positions:


~~~
struct s_cell
{
   bool north = true;
   bool east = true;
   bool south = true;
   bool west = true;
}
~~~

I try to create a 2D array of fixed length and pass it in 
parameter as a reference. Normally, in C, I would have used a 
pointer as parameter, and pass the address of the array. Here, I 
thought it would have been easier just to pass a slice of the 
array, since a slice is a reference to the original array. So I 
wrote the signature like this:


~~~
void main()
{  writeln("Maze generation demo");

   s_cell [5][5] maze;
   print_maze (maze);

}

void print_maze ( s_cell [][] maze )
{
}
~~~

My idea is that print_maze use a slice of what ever is sent in 
parameter. Unfortunately, I get the following error message:


~~~
Error: function `mprmaze.print_maze(s_cell[][] maze)` is not 
callable using argument types `(s_cell[5][5])`
  cannot pass argument `maze` of type `s_cell[5][5]` to parameter 
`s_cell[][] maze`

~~~

I tried to find a solution on the internet, but could not find 
anything, I stumble a lot on threads about Go or Rust language 
even if I specify "d language" in my search.


Else is there other ways to pass an array as reference using 
parameter modifiers like: ref,in,out ...


Else, can it be done the C way using pointers?

Thank you.


Re: need help to use C++ callback from garnet

2024-06-04 Thread Dakota via Digitalmars-d-learn

On Wednesday, 29 May 2024 at 09:01:13 UTC, evilrat wrote:

On Wednesday, 29 May 2024 at 07:47:01 UTC, Dakota wrote:

[...]



(here is the signature of callback)
https://github.com/microsoft/garnet/blob/ade2991f3737b9b5e3151d0dd0b614adfd4bcecd/libs/storage/Tsavorite/cc/src/device/async.h#L25

[...]


Thanks for the tips.


Re: How does one attach a manifest file to a D executable on Windows?

2024-06-02 Thread John Chapman via Digitalmars-d-learn

On Sunday, 2 June 2024 at 21:46:41 UTC, solidstate1991 wrote:
Well, it turns out I used the windres found in mingw instead of 
`rc.exe` since the latter cannot be found anywhere on my PC, 
even after reinstalling stuff. I need to hunt it down somehow.


rc.exe comes with the Windows SDK - it gets installed in one of 
the subfolders of "C:\Program Files (x86)\Windows Kits\10\bin" 
(on my machine it's in "10.0.22000.0\x64").


Re: How does one attach a manifest file to a D executable on Windows?

2024-06-02 Thread solidstate1991 via Digitalmars-d-learn

On Sunday, 2 June 2024 at 19:11:10 UTC, solidstate1991 wrote:


Added a few more line to my `resources.rc` file, it seems like 
the issue is the resource file not being touched at all.


I've put `dflags "resources.res" platform="windows"` in my 
`dub.sdl` file, it doesn't even care if there's a typo in the 
resource file's path.


Well, it turns out I used the windres found in mingw instead of 
`rc.exe` since the latter cannot be found anywhere on my PC, even 
after reinstalling stuff. I need to hunt it down somehow.


Re: How does one attach a manifest file to a D executable on Windows?

2024-06-02 Thread solidstate1991 via Digitalmars-d-learn

On Saturday, 25 May 2024 at 19:51:25 UTC, John Chapman wrote:


Not tested but from memory I do this:

1) Copy that first XML snippet from the page you linked, save 
to a file called example.exe.manifest
2) Create a resource script file called resources.rc, with this 
at the top:

   1 24 "example.exe.manifest"
3) Compile it with rc.exe
4) Include the resulting resources.res on your DMD command line

You might also need to call InitCommonControls or 
InitCommonControlsEx before creating any windows.


Added a few more line to my `resources.rc` file, it seems like 
the issue is the resource file not being touched at all.


I've put `dflags "resources.res" platform="windows"` in my 
`dub.sdl` file, it doesn't even care if there's a typo in the 
resource file's path.


Re: Socket and spawn()

2024-06-02 Thread Andy Valencia via Digitalmars-d-learn

On Sunday, 2 June 2024 at 17:46:09 UTC, bauss wrote:

If anything you should use a thread pool that each handles a 
set of sockets, instead of each thread being a single socket.


Yup, thread pool it is.  I'm still fleshing out the data 
structure which manages the incoming work presented to the pool, 
but here's what I have so far:


https://sources.vsta.org:7100/dlang/file?name=tiny/rotor.d=tip

Andy



Re: Socket and spawn()

2024-06-02 Thread bauss via Digitalmars-d-learn

On Friday, 31 May 2024 at 16:07:23 UTC, Andy Valencia wrote:
I'm coding a server which takes TCP connections.  I end up in 
the main thread with .accept() which hands me a Socket.  I'd 
like to hand this off to a spawn()'ed thread to do the actual 
work.


Aliases to mutable thread-local data not allowed.

Is there some standard way to get something which _isn't_ in 
TLS?  Or do I have to drop back to file descriptors and do my 
own socket handling?


TIA,
Andy


I just want to point out that you should not spawn a thread for 
each accepted socket. That is very bad and expensive.


You should instead make it non-blocking and use something like 
select to handle it.


If anything you should use a thread pool that each handles a set 
of sockets, instead of each thread being a single socket.


Re: How does one attach a manifest file to a D executable on Windows?

2024-06-02 Thread solidstate1991 via Digitalmars-d-learn

On Saturday, 25 May 2024 at 19:51:25 UTC, John Chapman wrote:

Not tested but from memory I do this:

1) Copy that first XML snippet from the page you linked, save 
to a file called example.exe.manifest
2) Create a resource script file called resources.rc, with this 
at the top:

   1 24 "example.exe.manifest"
3) Compile it with rc.exe
4) Include the resulting resources.res on your DMD command line

You might also need to call InitCommonControls or 
InitCommonControlsEx before creating any windows.



Did just that too, didn't change anything.


Re: Socket and spawn()

2024-05-31 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 31, 2024 6:28:27 PM MDT Andy Valencia via Digitalmars-d-learn 
wrote:
> On Friday, 31 May 2024 at 16:59:08 UTC, Jonathan M Davis wrote:
>
> Speaking as an old kernel engineer for the Sequent multiprocessor
> product line, this is all very comfortable to me.  I'm very glad
> that D has a suitable selection of spinlocks, process semaphores,
> and memory atomic operations.  I can work with this!

The way that D handles all of this is at its core the same as C/C++. The
main difference is that the type system assumes that anything that isn't
marked as shared or immutable is thread-local and can do optimizations based
on that (though I'm not sure that that actually happens in practice right
now). And in turn, you're supposed to get errors when you do stuff with a
shared object which isn't guaranteed to be thread-safe (though not all of
those checks are enabled by default at the moment).

The result of this is supposed to be that the portions of your code which
are operating on shared data are clearly segregated, whereas in C/C++, the
type system doesn't give you any way of knowing what's actively being shared
across threads. So, in principle, you're writing essentially what you want
have written in C/C++, but the type system is helping you catch when you
screw it up.

The annoying part is that because the compiler can't know when it's actually
thread-safe to access shared data (e.g. it has no clue when the programm
associates a mutex with a set of data), you have to use explicit casts to
thread-local to then be able to operate on the data when it is thread-safe
(unless the type is designed to be used as shared, in which case, it's doing
any necessary casting internally), whereas in C/C++, since the type system
doesn't know or care about thread safety, it'll just let you access data
whether it's properly protected or not.

So, some folks get annoyed by the necessary casting, but in theory, it's the
type system helping to minimize the risk of you shooting yourself in the
foot. The idioms involved are basically the same as those used in C/C++
though, so anyone who understands those should be able to write thread-safe
code in D fairly easily once they understand how shared works.

> > In any case, you can freely cast between thread-local and
> > shared. It's just that you need to be sure that when you do
> > that, you're not violating the type system by having a
> > thread-local reference to shared data access that shared data
> > without first protecting it with a mutex.
>
> That was the trick for me; TLS implied to me that an
> implementation would be free to arrange that the address of a
> variable in one thread's TLS would not necessarily be accessible
> from another thread.  Now I'm clearer on the usage of the term
> WRT the D runtime.  All good.

If you have a module-level or static variable that isn't shared or
immutable, then each thread will get its own copy. So, those _might_ end up
in TLS (I'm not sure if they are right now or not), but if you're just
creating stuff on the fly, none of it is actually in TLS. And it's very
common when dealing with shared or immutable data to create it first as
thread-local and then cast it, since you know that it's not actually shared
across threads at that point, and it's easier to construct that way. If we
did want to start using TLS all over the place, then the casts would have to
take that into account somehow, but I don't expect that that will happen.

- Jonathan M Davis





Re: Socket and spawn()

2024-05-31 Thread Andy Valencia via Digitalmars-d-learn

On Friday, 31 May 2024 at 16:59:08 UTC, Jonathan M Davis wrote:
Strictly speaking, unless you're dealing with a module or 
static-level variable, the object is not in TLS. It's treated 
as thread-local by the type system, and the type system will 
assume that no other thread has access to it, but you can 
freely cast it to shared or immutable and pass it across 
threads. It's just that it's up to you to make sure that you 
don't have a thread-local reference to shared data that isn't 
protected in a fashion that accessing the thread-local 
references is guarantee to be thread-safe (e.g. the appropriate 
mutex has been locked).


Thank you; this is the most complete explanation I've found yet 
for hwo to look at data sharing in D.


On the other hand, if you're actively sharing an object across 
threads, then you cast it to shared and give it to the other 
thread. But then you have to use an appropriate 
thread-synchronization mechanism (likely a mutex in the case of 
a socket) to ensure that accessing the object is thread-safe.


Speaking as an old kernel engineer for the Sequent multiprocessor 
product line, this is all very comfortable to me.  I'm very glad 
that D has a suitable selection of spinlocks, process semaphores, 
and memory atomic operations.  I can work with this!


In any case, you can freely cast between thread-local and 
shared. It's just that you need to be sure that when you do 
that, you're not violating the type system by having a 
thread-local reference to shared data access that shared data 
without first protecting it with a mutex.


That was the trick for me; TLS implied to me that an 
implementation would be free to arrange that the address of a 
variable in one thread's TLS would not necessarily be accessible 
from another thread.  Now I'm clearer on the usage of the term 
WRT the D runtime.  All good.


Thanks again,
Andy



Re: Socket and spawn()

2024-05-31 Thread Andy Valencia via Digitalmars-d-learn

On Friday, 31 May 2024 at 19:48:37 UTC, kdevel wrote:
Have you taken into consideration that each of the 
(pre-spawned) threads
can call accept()? Your program may also accept in multiple 
processes on the same socket. [1]


Yes, but I am planning on some global behavior--mostly concerning 
resource consumption--where that would make implementing the 
policy harder.


I've indeed done the cast-to-shared and then cast-to-unshared and 
it's working fine.


BTW, if the strategy forward is where the type system is going to 
assist with flagging code paths requiring allowance for multiple 
threads, it would be nice if the modifiers were available 
symmetrically.  "shared" and "unshared", "mutable" and 
"immutable", and so forth?  I'm using:


alias Unshared(T) = T;
alias Unshared(T: shared U, U) = U;

and that's fine, but for core semantics of the language, it might 
make sense to treat these as first class citizens.


Andy



Re: Socket and spawn()

2024-05-31 Thread kdevel via Digitalmars-d-learn

On Friday, 31 May 2024 at 16:07:23 UTC, Andy Valencia wrote:
I'm coding a server which takes TCP connections.  I end up in 
the main thread with .accept() which hands me a Socket.  I'd 
like to hand this off to a spawn()'ed thread to do the actual 
work.


Have you taken into consideration that each of the (pre-spawned) 
threads
can call accept()? Your program may also accept in multiple 
processes

on the same socket. [1]

[1] 
https://stackoverflow.com/questions/11488453/can-i-call-accept-for-one-socket-from-several-threads-simultaneously


Re: Socket and spawn()

2024-05-31 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, May 31, 2024 10:07:23 AM MDT Andy Valencia via Digitalmars-d-learn 
wrote:
> I'm coding a server which takes TCP connections.  I end up in the
> main thread with .accept() which hands me a Socket.  I'd like to
> hand this off to a spawn()'ed thread to do the actual work.
>
>  Aliases to mutable thread-local data not allowed.
>
> Is there some standard way to get something which _isn't_ in TLS?
>   Or do I have to drop back to file descriptors and do my own
> socket handling?
>
> TIA,
> Andy

Strictly speaking, unless you're dealing with a module or static-level
variable, the object is not in TLS. It's treated as thread-local by the type
system, and the type system will assume that no other thread has access to
it, but you can freely cast it to shared or immutable and pass it across
threads. It's just that it's up to you to make sure that you don't have a
thread-local reference to shared data that isn't protected in a fashion that
accessing the thread-local references is guarantee to be thread-safe (e.g.
the appropriate mutex has been locked).

So, if you're just passing it to another thread, and that other thread is
all that uses the object, then you would temporarily cast it to shared or
immutable, give it to the other thread, and then that thread would cast it
back to thread-local to use it, and the original thread would have nothing
to do with it any longer.

On the other hand, if you're actively sharing an object across threads, then
you cast it to shared and give it to the other thread. But then you have to
use an appropriate thread-synchronization mechanism (likely a mutex in the
case of a socket) to ensure that accessing the object is thread-safe.

So, typically, you would lock a mutex to ensure that no other thread is
accessing the object, and then you temporarily cast away shared while the
object is protected by the mutex so that you can do whatever you need to do
with the object, and once you're ready to release the mutex, you make sure
that no thread-local references to the object remain before releasing the
mutex. So, any code actually operating on the object would do so while it's
typed as thread-local, and the compiler would complain if you accidentally
accessed it through the shared referenc to the data (though the compiler
doesn't currently catch all such cases - the -preview=nosharedaccess switch
turns on more of the checks, and that's supposed to be become the default
eventually, but it hasn't yet).

In any case, you can freely cast between thread-local and shared. It's just
that you need to be sure that when you do that, you're not violating the
type system by having a thread-local reference to shared data access that
shared data without first protecting it with a mutex. And that typically
means not having any thread-local references to the shared data except when
the mutex is locked. But if all you're doing is passing an object across
threads, then it's pretty straightforward, since you just cast it to shared
or immutable to be able to pass it across threads and then cast back to
thread-local on the other side to use it as normal again (you just need to
make sure that you don't leave a reference to the data on the original
thread when you do that).

- Jonathan M Davis





Socket and spawn()

2024-05-31 Thread Andy Valencia via Digitalmars-d-learn
I'm coding a server which takes TCP connections.  I end up in the 
main thread with .accept() which hands me a Socket.  I'd like to 
hand this off to a spawn()'ed thread to do the actual work.


Aliases to mutable thread-local data not allowed.

Is there some standard way to get something which _isn't_ in TLS? 
 Or do I have to drop back to file descriptors and do my own 
socket handling?


TIA,
Andy



Re: need help to use C++ callback from garnet

2024-05-29 Thread evilrat via Digitalmars-d-learn

On Wednesday, 29 May 2024 at 07:47:01 UTC, Dakota wrote:
I try use 
https://github.com/microsoft/garnet/blob/main/libs/storage/Tsavorite/cc/src/device/native_device_wrapper.cc from D



Not sure how to make this work with D:

```c++
	EXPORTED_SYMBOL FASTER::core::Status 
NativeDevice_ReadAsync(NativeDevice* device, uint64_t source, 
void* dest, uint32_t length, FASTER::core::AsyncIOCallback 
callback, void* context) {
		return device->ReadAsync(source, dest, length, callback, 
context);

}

	EXPORTED_SYMBOL FASTER::core::Status 
NativeDevice_WriteAsync(NativeDevice* device, const void* 
source, uint64_t dest, uint32_t length, 
FASTER::core::AsyncIOCallback callback, void* context) {
		return device->WriteAsync(source, dest, length, callback, 
context);

}
```

I need to define `FASTER::core::AsyncIOCallback callback` from 
D, any way to workaround ? (like modify garnet source code to 
support pass a C function callback)


I am newbie to C++ and D, any help will be appreciate



(here is the signature of callback)
https://github.com/microsoft/garnet/blob/ade2991f3737b9b5e3151d0dd0b614adfd4bcecd/libs/storage/Tsavorite/cc/src/device/async.h#L25

```cpp
typedef void(*AsyncIOCallback)(IAsyncContext* context, Status 
result, size_t bytes_transferred);

```

This can be written as following to match namespace and mangling 
scheme, assuming IAsyncContext is opaque pointer here, though I 
don't remember if enum need namespace as well.

But no guarantess anyways, try it and adapt it.
Also I can't remember if string list makes proper namespace or 
you should put `FASTER.core` instead (without quotes).


```d
enum Status : ubyte {
  Ok = 0,
  Pending = 1,
  NotFound = 2,
  OutOfMemory = 3,
  IOError = 4,
  Corruption = 5,
  Aborted = 6,
}

extern(C++, "FASTER", "core")
class IAsyncContext;

alias AsyncIOCallback = extern(C++, "FASTER", "core") void 
function(IAsyncContext context, Status result, size_t 
bytes_transferred);

```


need help to use C++ callback from garnet

2024-05-29 Thread Dakota via Digitalmars-d-learn
I try use 
https://github.com/microsoft/garnet/blob/main/libs/storage/Tsavorite/cc/src/device/native_device_wrapper.cc from D



Not sure how to make this work with D:

```c++
	EXPORTED_SYMBOL FASTER::core::Status 
NativeDevice_ReadAsync(NativeDevice* device, uint64_t source, 
void* dest, uint32_t length, FASTER::core::AsyncIOCallback 
callback, void* context) {
		return device->ReadAsync(source, dest, length, callback, 
context);

}

	EXPORTED_SYMBOL FASTER::core::Status 
NativeDevice_WriteAsync(NativeDevice* device, const void* source, 
uint64_t dest, uint32_t length, FASTER::core::AsyncIOCallback 
callback, void* context) {
		return device->WriteAsync(source, dest, length, callback, 
context);

}
```

I need to define `FASTER::core::AsyncIOCallback callback` from D, 
any way to workaround ? (like modify garnet source code to 
support pass a C function callback)


I am newbie to C++ and D, any help will be appreciate


Re: Get milliseconds from time and construct time based on milliseconds

2024-05-29 Thread bauss via Digitalmars-d-learn
On Tuesday, 28 May 2024 at 23:18:46 UTC, Steven Schveighoffer 
wrote:

On Tuesday, 28 May 2024 at 18:41:02 UTC, bauss wrote:
On Tuesday, 28 May 2024 at 18:29:17 UTC, Ferhat Kurtulmuş 
wrote:

On Tuesday, 28 May 2024 at 17:37:42 UTC, bauss wrote:
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime 
based on milliseconds?


Thanks


Unixtime might be what you want:

import std;

import std.datetime;
import std.stdio;

void main() {
// Get the current time in the UTC time zone
    auto currentTime = Clock.currTime();

// Convert the time to the Unix epoch 
(1970-01-01T00:00:00Z)
    Duration unixTime = currentTime - 
SysTime(DateTime(1970, 1, 1), UTC());


You can do `SysTime(unixTimeToStdTime(0))` to get a SysTime 
that is at the unix epoch.




Also figured out the second question based on your result.

Simply doing:

```
SysTime(DateTime(1970, 1, 1), UTC()) + 
dur!"msecs"(milliseconds)

```

Seems to work.


Note there is an `msecs` function:

```d
SysTime(unixTimeToStdTime(0)) + milliseconds.msecs;
```

https://dlang.org/phobos/std_datetime_systime.html#unixTimeToStdTime
https://dlang.org/phobos/core_time.html#msecs

-Steve


Thanks! That's a lot cleaner


Re: Get milliseconds from time and construct time based on milliseconds

2024-05-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tuesday, 28 May 2024 at 18:41:02 UTC, bauss wrote:

On Tuesday, 28 May 2024 at 18:29:17 UTC, Ferhat Kurtulmuş wrote:

On Tuesday, 28 May 2024 at 17:37:42 UTC, bauss wrote:
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime 
based on milliseconds?


Thanks


Unixtime might be what you want:

import std;

import std.datetime;
import std.stdio;

void main() {
// Get the current time in the UTC time zone
    auto currentTime = Clock.currTime();

// Convert the time to the Unix epoch 
(1970-01-01T00:00:00Z)
    Duration unixTime = currentTime - 
SysTime(DateTime(1970, 1, 1), UTC());


You can do `SysTime(unixTimeToStdTime(0))` to get a SysTime that 
is at the unix epoch.




Also figured out the second question based on your result.

Simply doing:

```
SysTime(DateTime(1970, 1, 1), UTC()) + dur!"msecs"(milliseconds)
```

Seems to work.


Note there is an `msecs` function:

```d
SysTime(unixTimeToStdTime(0)) + milliseconds.msecs;
```

https://dlang.org/phobos/std_datetime_systime.html#unixTimeToStdTime
https://dlang.org/phobos/core_time.html#msecs

-Steve


Re: Get milliseconds from time and construct time based on milliseconds

2024-05-28 Thread bauss via Digitalmars-d-learn

On Tuesday, 28 May 2024 at 18:29:17 UTC, Ferhat Kurtulmuş wrote:

On Tuesday, 28 May 2024 at 17:37:42 UTC, bauss wrote:
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime 
based on milliseconds?


Thanks


Unixtime might be what you want:

import std;

import std.datetime;
import std.stdio;

void main() {
// Get the current time in the UTC time zone
    auto currentTime = Clock.currTime();

// Convert the time to the Unix epoch 
(1970-01-01T00:00:00Z)
    Duration unixTime = currentTime - 
SysTime(DateTime(1970, 1, 1), UTC());


// Get the total milliseconds
long milliseconds = unixTime.total!"msecs";

// Print the Unix time in milliseconds
writeln("Unix time in milliseconds: ", milliseconds);
}


Thanks a lot.

Also figured out the second question based on your result.

Simply doing:

```
SysTime(DateTime(1970, 1, 1), UTC()) + dur!"msecs"(milliseconds)
```

Seems to work.


Re: Get milliseconds from time and construct time based on milliseconds

2024-05-28 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Tuesday, 28 May 2024 at 17:37:42 UTC, bauss wrote:
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime 
based on milliseconds?


Thanks


Unixtime might be what you want:

import std;

import std.datetime;
import std.stdio;

void main() {
// Get the current time in the UTC time zone
    auto currentTime = Clock.currTime();

// Convert the time to the Unix epoch 
(1970-01-01T00:00:00Z)
    Duration unixTime = currentTime - SysTime(DateTime(1970, 
1, 1), UTC());


// Get the total milliseconds
long milliseconds = unixTime.total!"msecs";

// Print the Unix time in milliseconds
writeln("Unix time in milliseconds: ", milliseconds);
}



Get milliseconds from time and construct time based on milliseconds

2024-05-28 Thread bauss via Digitalmars-d-learn
I have two questions that I can't seem to find a solution to 
after looking at std.datetime.


First question is how do I get the current time but in 
milliseconds?


Second is how do I construct a time ex. systime or datetime based 
on milliseconds?


Thanks


Re: Hide console on Windows with app running SDL2

2024-05-28 Thread bauss via Digitalmars-d-learn
On Tuesday, 28 May 2024 at 12:45:39 UTC, Steven Schveighoffer 
wrote:

On Tuesday, 28 May 2024 at 12:35:42 UTC, bauss wrote:
Running into a couple of problems trying to hide the console 
that opens when running an app that uses sdl2.


First of all I am trying to compile with this using dub:

```
"lflags": ["/SUBSYSTEM:windows"]
```

However that gives me the following error:

```
error LNK2019: unresolved external symbol WinMain
```

And then if I add a WinMain like below:

```
extern (Windows) int WinMain() { return 0; }
```

Then of course it doesn't work, but what is the obvious way to 
solve this?


I basically just want to hide the console, but nothing seems 
to work straight out of the box.


I think this is still relevant: 
https://wiki.dlang.org/D_for_Win32


-Steve


Thanks a lot, that helped and solved the issue


Re: Hide console on Windows with app running SDL2

2024-05-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tuesday, 28 May 2024 at 12:35:42 UTC, bauss wrote:
Running into a couple of problems trying to hide the console 
that opens when running an app that uses sdl2.


First of all I am trying to compile with this using dub:

```
"lflags": ["/SUBSYSTEM:windows"]
```

However that gives me the following error:

```
error LNK2019: unresolved external symbol WinMain
```

And then if I add a WinMain like below:

```
extern (Windows) int WinMain() { return 0; }
```

Then of course it doesn't work, but what is the obvious way to 
solve this?


I basically just want to hide the console, but nothing seems to 
work straight out of the box.


I think this is still relevant: https://wiki.dlang.org/D_for_Win32

-Steve


Re: Implementation Details

2024-05-27 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 28/05/2024 12:54 PM, Ruby The Roobster wrote:
As of late, I have taken up an interest in learning about how the D 
language is implemented at a compiler level, specifically the GC 
implementation.  Unfortunately, the source code is poorly documented, 
and is too large to simply read all of it in a reasonable amount of 
time.  If anyone here can help me, or at least point me to relevant 
resources, I would be very grateful.


From a theory standpoint this book should give you a pretty good 
overview of how GC's work. It is the book I recommend for introduction 
to GC's.


https://www.amazon.com/Garbage-Collection-Handbook-International-Perspectives-dp-1032218037/dp/1032218037/ref=dp_ob_title_bk

But yes that GC is very hard to get into, and its been tacked on over 
the years which make it even harder to untangle. Plus there is a memory 
allocator in there too.


Implementation Details

2024-05-27 Thread Ruby The Roobster via Digitalmars-d-learn
As of late, I have taken up an interest in learning about how the 
D language is implemented at a compiler level, specifically the 
GC implementation.  Unfortunately, the source code is poorly 
documented, and is too large to simply read all of it in a 
reasonable amount of time.  If anyone here can help me, or at 
least point me to relevant resources, I would be very grateful.


Re: Problem with clear on shared associative array?

2024-05-27 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 28/05/2024 12:36 PM, Andy Valencia wrote:

On Monday, 27 May 2024 at 04:04:03 UTC, mw wrote:

Pls NOTE: it is
a   `sharded` (meaning trunk-ed) NON-concurrent map,
not `shared` concurrent map.


Assuming I put it in shared memory, in what way is it not able to be 
used concurrently?  It seems to have the needed lock operations?


Thanks,
Andy


A concurrent data structure handles all of this for you.

AA's are not concurrent because it doesn't offer any protection.

Protecting a data structure with a mutex doesn't make it concurrent, but 
it may allow you to use it concurrently safely. Subtle difference!


Re: Problem with clear on shared associative array?

2024-05-27 Thread Andy Valencia via Digitalmars-d-learn

On Monday, 27 May 2024 at 04:04:03 UTC, mw wrote:

Pls NOTE: it is
a   `sharded` (meaning trunk-ed) NON-concurrent map,
not `shared` concurrent map.


Assuming I put it in shared memory, in what way is it not able to 
be used concurrently?  It seems to have the needed lock 
operations?


Thanks,
Andy



Re: Problem with clear on shared associative array?

2024-05-26 Thread mw via Digitalmars-d-learn

On Monday, 27 May 2024 at 00:43:47 UTC, Serg Gini wrote:

On Sunday, 26 May 2024 at 20:15:54 UTC, Andy Valencia wrote:
For others wrestling with this issue, I found out how to cast 
to unshared at this article:




You can check also this solution 
https://github.com/DmitryOlshansky/sharded-map



Pls NOTE: it is
a   `sharded` (meaning trunk-ed) NON-concurrent map,
not `shared` concurrent map.

These two words looks similar, but the meaning is very different.




Re: Problem with clear on shared associative array?

2024-05-26 Thread Serg Gini via Digitalmars-d-learn

On Sunday, 26 May 2024 at 20:15:54 UTC, Andy Valencia wrote:
For others wrestling with this issue, I found out how to cast 
to unshared at this article:




You can check also this solution 
https://github.com/DmitryOlshansky/sharded-map


Re: Problem with clear on shared associative array?

2024-05-26 Thread Andy Valencia via Digitalmars-d-learn

On Sunday, 26 May 2024 at 20:00:50 UTC, Jonathan M Davis wrote:
No operation on an associative array is thread-safe. As such, 
you should not be doing _any_ operation on a shared AA without 
first locking a mutex to protect it. Then you need to cast away 
shared to access or mutate it or do whatever it is you want to 
do with it other than pass it around. And then when you're 
done, you make sure that no thread-local references to the AA 
exist, and you release the mutex.

...


Thank you, that's exactly the big picture explanation I was 
hoping for.


For others wrestling with this issue, I found out how to cast to 
unshared at this article:


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

Andy



Re: Problem with clear on shared associative array?

2024-05-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 26, 2024 8:39:53 AM MDT Andy Valencia via Digitalmars-d-learn 
wrote:
> The following code fails to compile; it appears from the error
> message that the library's clear() function is not ready to act
> on a shared AA?
>
> synchronized class F {
>
> private:
>  string[int] mydict;
>
> public:
>  void clear() {
>  this.mydict.clear();
>  }
> }
>
> void
> main()
> {
>  auto f = new shared F();
>  f.clear();
> }

No operation on an associative array is thread-safe. As such, you should not
be doing _any_ operation on a shared AA without first locking a mutex to
protect it. Then you need to cast away shared to access or mutate it or do
whatever it is you want to do with it other than pass it around. And then
when you're done, you make sure that no thread-local references to the AA
exist, and you release the mutex. This is true for any type which is not
specifically designed to be shared, and none of the built-in types are
designed to be shared. They will work as shared so long as you protect them
appropriately and then temporarily cast away shared to operate on them as
thread-local, but they should never be mutated as shared, and it's on you to
make sure that the object is actually protected appropriately when you cast
away shared, since the language has no way of knowing when that's actually
safe to do. It can just prevent you from accidentally accessing an object
when it's shared, since when it's shared, the type system marks it as shared
across threads and thus not thread-safe to access.

The language is supposed to prevent you from doing any operations on a
shared object which are not guaranteed to be thread-safe (which is pretty
much anything other than passing it around by reference or pointer), but
unfortunately, since that wasn't entirely implemented up front, some of
those checks are currently behind the -preview=nosharedaccess flag and will
be made the default at some point in the future (but not now). So, some
shared operations may work when they really shouldn't, but the compiler will
prevent you from calling a function like clear, because it operates on
thread-local variables, not shared ones.

And with regards to AAs, you will need to be particularly careful with the
in operator, because it returns a pointer a value in the AA. So, if you cast
away shared to operate on it and then use in, you'll get a thread-local
pointer to the AA, meaning that the lock needs to stay in place as long as
that pointer is around, whereas a function like clear is done as soon as its
been called, so unless you're doing more with the AA at that point, you
could release the lock then.

Using synchronized is one way to get a mutex, and a synchronized function is
implicitly shared, so your clear function is both synchronized and shared,
meaning that you can call it on a shared object, and it will lock a mutex
when it's called, but you still need to cast away shared from mydict to be
able to call anything on it. The compiler is not smart enough to know that
removing shared is thread-safe within your function, so it will not do it
for you, and the clear function for AAs can't work on shared AAs, because it
has no way of guaranteeing that that's thread-safe. So, the solution is that
you must explicitly removed shared temporarily to call clear when you know
that it's thread-safe to do so.

- Jonathan M Davis





Problem with clear on shared associative array?

2024-05-26 Thread Andy Valencia via Digitalmars-d-learn
The following code fails to compile; it appears from the error 
message that the library's clear() function is not ready to act 
on a shared AA?


synchronized class F {

private:
string[int] mydict;

public:
void clear() {
this.mydict.clear();
}
}

void
main()
{
auto f = new shared F();
f.clear();
}


Re: How does one attach a manifest file to a D executable on Windows?

2024-05-25 Thread John Chapman via Digitalmars-d-learn

On Saturday, 25 May 2024 at 13:13:08 UTC, solidstate1991 wrote:

No, I meant something like this:

https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview


Not tested but from memory I do this:

1) Copy that first XML snippet from the page you linked, save to 
a file called example.exe.manifest
2) Create a resource script file called resources.rc, with this 
at the top:

   1 24 "example.exe.manifest"
3) Compile it with rc.exe
4) Include the resulting resources.res on your DMD command line

You might also need to call InitCommonControls or 
InitCommonControlsEx before creating any windows.


Re: How does one attach a manifest file to a D executable on Windows?

2024-05-25 Thread solidstate1991 via Digitalmars-d-learn

On Friday, 24 May 2024 at 21:26:12 UTC, Ferhat Kurtulmuş wrote:

I think this is what you need

https://github.com/aferust/doitlater/tree/master/views/res


No, I meant something like this:

https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview


Re: Parallel safe associative array?

2024-05-24 Thread mw via Digitalmars-d-learn

https://code.dlang.org/packages/rust_interop_d

wrapped:

DashMap: is an implementation of a concurrent associative 
array/hashmap in Rust.


Re: How does one attach a manifest file to a D executable on Windows?

2024-05-24 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Friday, 24 May 2024 at 21:04:53 UTC, Ferhat Kurtulmuş wrote:

On Friday, 24 May 2024 at 19:07:24 UTC, solidstate1991 wrote:
I have tried resource compiling, then using `dflags` in dug to 
add the resulting obj file, but I still get the issue of the 
old GUI style.


I did that before, but I don't remember now. Probably you will 
figure that out based on this.


https://gitlab.com/aferust/gtkdappcreator/-/tree/master/win_res?ref_type=heads


I think this is what you need

https://github.com/aferust/doitlater/tree/master/views/res



Re: How does one attach a manifest file to a D executable on Windows?

2024-05-24 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Friday, 24 May 2024 at 19:07:24 UTC, solidstate1991 wrote:
I have tried resource compiling, then using `dflags` in dug to 
add the resulting obj file, but I still get the issue of the 
old GUI style.


I did that before, but I don't remember now. Probably you will 
figure that out based on this.


https://gitlab.com/aferust/gtkdappcreator/-/tree/master/win_res?ref_type=heads


Parallel safe associative array?

2024-05-24 Thread Andy Valencia via Digitalmars-d-learn
I was playing with parallel programming, and experienced 
"undefined behavior" when storing into an Associative Array in 
parallel.  Guarding the assignments with a synchronized barrier 
fixed it, of course.  And obviously loading down your raw AA with 
thread barriers would be foolish.


But this set me searching through the library for a standard 
Associative Array construct which _is_ thread safe?  It didn't 
jump out at me.  I know I can place such a thing within a 
synchronized class, but I was wondering if there's a standard AA 
which has the standard usage but is safe when called in parallel?


Thanks,
Andy



Re: Recommendations on porting Python to D

2024-05-23 Thread mw via Digitalmars-d-learn

On Friday, 3 May 2024 at 17:53:41 UTC, mw wrote:

On Friday, 3 May 2024 at 17:38:10 UTC, Chris Piker wrote:

On Thursday, 25 April 2024 at 16:57:53 UTC, mw wrote:

[...]


Thanks for the suggestions.  I put the question aside for a 
bit, but yesterday ran across a python transpiler here:


  https://github.com/py2many/py2many

It already has support for C++, Go and others.  Since I have 
mountains of python code created over many years, maybe it 
would be worth contributing to this project out of self 
interest.


Can you take a look at py2many and see what you think about 
it?  Getting D on the support list might be good.


(Haven't checked its own implementation and output code 
quality.)


But it says has output for Kotlin, Dart, these two languages 
are similar to D syntactically, so will be a good start.


I took another quick look of the project, it uses the Python 
builtin `ast` module as parser, and visitor design pattern to 
implement the transcompiler, so I think it's of decent quality.


HTH.


Re: Anybody know about SDL and particularly SDL_TTF initialization?

2024-05-23 Thread Jerry via Digitalmars-d-learn

On Sunday, 12 May 2024 at 20:13:04 UTC, WhatMeWorry` wrote:


INFO: SDL loaded v2.30.2
INFO: SDL initialized: 0
INFO: TTF loaded: v2.0.14
Error Program exited with code -1073741819


Something hit a null pointer, time to fire up the debugger :)




Re: Anybody know about SDL and particularly SDL_TTF initialization?

2024-05-22 Thread Danny Arends via Digitalmars-d-learn

On Sunday, 12 May 2024 at 20:13:04 UTC, WhatMeWorry` wrote:

This should be trivial, right?
I've been looking at existing D repo code for hours. Can't 
figure why TTF_Init doesn't work?

It would help if I could figure out how to use SDL_GetError()

INFO: SDL loaded v2.30.2
INFO: SDL initialized: 0
INFO: TTF loaded: v2.0.14
Error Program exited with code -1073741819


  loadSDL();
  SDL_version v;
  SDL_GetVersion();
  toStdout("SDL loaded v%d.%d.%d", v.major, v.minor, v.patch);
  auto initSDL = SDL_Init(SDL_INIT_EVERYTHING);  // returns 0 
on success

  toStdout("SDL initialized: %d", initSDL);

  auto loadTTF = loadSDLTTF();
  SDL_TTF_VERSION();
  toStdout("TTF loaded: v%d.%d.%d", v.major, v.minor, v.patch);
  auto initTTF = TTF_Init();  // SDL must be initialized before 
calls to this library


No idea why this fails, seems alright to me. You can use: 
TTF_GetError() for a human-readable error message,when the call 
to TTF_Init() fails (return -1).


Good luck
Danny


Re: __gshared is "somewhat" transitive, isn't it ?

2024-05-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thursday, 16 May 2024 at 17:04:09 UTC, user1234 wrote:

Given

```d
struct S
{
int member;
}

__gshared S s;
```

It's clear that `s.member` is `__gshared` too, right ?
What does happen for

```d
struct S
{
int member;
static int globalMember;
}

__gshared S s;
```

Is then `S.globalMember` a TLS variable ? (I'd expect that)


`__gshared` is a storage class. It means, store this thing in the 
global memory segment. `static` storage class means store this 
thing in TLS.


Storage classes are *not* transitive, and they are not type 
constructors. They optionally might apply a type constructor to 
the type (such as the `const` storage class), but not always.


So in this case `typeof(s)` is `S`, not `__gshared S`. `s.member` 
is in the global segment since structs members are placed within 
the struct memory location (in this case, the global memory 
segment).


`globalMember` is placed in TLS because it's storage class is 
`static`, and `static` means, do not store with the instance 
(which for `s` would mean the global memory segment), but rather 
in TLS.


-Steve


Re: Setting field of struct object

2024-05-14 Thread Menjanahary R. R. via Digitalmars-d-learn

On Monday, 22 January 2024 at 08:54:21 UTC, Danilo wrote:

On Monday, 22 January 2024 at 08:35:01 UTC, Joel wrote:

[...]


Nonetheless, this usually used with Objects (new class/struct 
instances), like so:

```d
import std;

[...]


Fluent Interface 


Re: FIFO

2024-05-14 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote:

On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote:

https://dlang.org/phobos/std_container_slist.html

This is a stack, isn't it?  LIFO?

Ahh yes. Then use dlist


Thank you.  I read its source, and was curious so I wrote a 
small performance measurement: put 10,000 things in a FIFO, 
pull them back out, and loop around that 10,000 times.  My FIFO 
resulted in:


Also try the code I gave in this thread:
https://forum.dlang.org/post/fgzvdhkdyevtzznya...@forum.dlang.org

In fact, please use this facility in the standard library: 
https://dlang.org/phobos/std_datetime_stopwatch.html#benchmark


SDB@79


Re: FIFO

2024-05-13 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote:

On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote:

https://dlang.org/phobos/std_container_slist.html

This is a stack, isn't it?  LIFO?

Ahh yes. Then use dlist


Thank you.  I read its source, and was curious so I wrote a 
small performance measurement: put 10,000 things in a FIFO, 
pull them back out, and loop around that 10,000 times.  My FIFO 
resulted in:


real0m1.589s
user0m1.585s
sys 0m0.004s

And the dlist based one:

real0m4.731s
user0m5.211s
sys 0m0.308s

Representing the FIFO as a linked list clearly has its cost, 
but I found the increased system time interesting.  OS memory 
allocations maybe?


The code is spaghetti, fifo/dlist, but it seemed the easiest 
way to see the two API's being used side by side:


version(fifo) {
import tiny.fifo : FIFO;
} else {
import std.container.dlist : DList;
}

const uint ITERS = 10_000;
const uint DEPTH = 10_000;

void
main()
{
version(fifo) {
auto d = FIFO!uint();
} else {
auto d = DList!uint();
}
foreach(_; 0 .. ITERS) {
foreach(x; 0 .. DEPTH) {
version(fifo) {
d.add(x);
} else {
d.insertBack(x);
}
}
foreach(x; 0 .. DEPTH) {
version(fifo) {
assert(x == d.next());
} else {
assert(x == d.front());
d.removeFront();
}
}
}
}


thank you for sharing the results. Everything I read about queues 
recommends doublylinked lists. With your array based 
implementatio if you are consuming the elements faster than 
pushing new elements, your array buffer never resize which is 
costly. This should explain why your array based queue is more 
performant.


Re: FIFO

2024-05-13 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote:


Representing the FIFO as a linked list clearly has its cost, 
but I found the increased system time interesting.  OS memory 
allocations maybe?


I know you want FIFO, I usually keep this on hand for fixed size 
LIFO; It can easily convert to FIFO and doesn't use LinkedList:


```d
class LIFO(T)
{
  T * element;
  size_t length, size;
  this(size_t s) {
element = cast(T*)new T[s];
length = s;
  }
  auto rewind() => size = length;

  bool empty() => !size;
  auto front() => element[size - 1];
  auto popFront() => --size;

  auto pop() => empty ? T(0) : element[--size];
  alias push = insertFront;
  auto insertFront(T value)
  in(size < length, "Stack is overflow!")
=> element[size++] = value;

  auto ref opDollar() => length;
  auto ref opIndex(size_t i) => element[i];
  auto ref opSlice(size_t first, size_t last)
=> element[first..last];

} unittest {

  enum test = 7;
  auto stack = new LIFO!size_t(test);

  assert(!stack.size);
  foreach (prime; 1..test + 1)
  {
stack.insertFront(prime);
  }
  assert(stack.size == test); // == 7

  stack.writeln(": ", stack.length); // [7, 6, 5, 4, 3, 2, 1]: 7
  stack[$/2].writeln("-", stack[0]); // 4-1


  stack.rewind();
  stack.size.write(": ["); // 10:
  while (auto next = stack.pop)
  {
if (next == 1) next.writeln("]");
else next.write(", ");
  }
  stack.size.writeln; // 0
  stack.rewind();
  assert(stack.size == test);
}

SDB@79



Re: FIFO

2024-05-13 Thread Andy Valencia via Digitalmars-d-learn

On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote:

https://dlang.org/phobos/std_container_slist.html

This is a stack, isn't it?  LIFO?

Ahh yes. Then use dlist


Thank you.  I read its source, and was curious so I wrote a small 
performance measurement: put 10,000 things in a FIFO, pull them 
back out, and loop around that 10,000 times.  My FIFO resulted in:


real0m1.589s
user0m1.585s
sys 0m0.004s

And the dlist based one:

real0m4.731s
user0m5.211s
sys 0m0.308s

Representing the FIFO as a linked list clearly has its cost, but 
I found the increased system time interesting.  OS memory 
allocations maybe?


The code is spaghetti, fifo/dlist, but it seemed the easiest way 
to see the two API's being used side by side:


version(fifo) {
import tiny.fifo : FIFO;
} else {
import std.container.dlist : DList;
}

const uint ITERS = 10_000;
const uint DEPTH = 10_000;

void
main()
{
version(fifo) {
auto d = FIFO!uint();
} else {
auto d = DList!uint();
}
foreach(_; 0 .. ITERS) {
foreach(x; 0 .. DEPTH) {
version(fifo) {
d.add(x);
} else {
d.insertBack(x);
}
}
foreach(x; 0 .. DEPTH) {
version(fifo) {
assert(x == d.next());
} else {
assert(x == d.front());
d.removeFront();
}
}
}
}


Re: What prevents ImportC from using .h directly?

2024-05-13 Thread Nick Treleaven via Digitalmars-d-learn

On Sunday, 12 May 2024 at 21:34:30 UTC, Chris Piker wrote:
So, why does ImportC need *.c files exclusively?  I'm sure it 
solves a problem, but I don't know what that problem is.


Support for headers has been worked on, but had to be reverted:
https://issues.dlang.org/show_bug.cgi?id=23479


Re: Find homography in D?

2024-05-13 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote:

Hi,

Someone can point me to a D implementation of the classical 
OpenCV find homography matrix?


Thank you,
Paolo


Now, we can do image stitching using DCV. It needs improvements 
though.


https://github.com/libmir/dcv/tree/master/examples/imagestitchinghomography


Re: FIFO

2024-05-13 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable jumped 
out at me.  I wrote the following, but as a newbie, would be 
happy to receive any suggestions or observations.  TIA!


[...]


I don't know your use case, maybe you have a similar problem I 
had to solve years ago.


https://forum.dlang.org/post/xktftztisodpngcow...@forum.dlang.org


Re: FIFO

2024-05-12 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Sunday, 12 May 2024 at 21:08:24 UTC, Andy Valencia wrote:

On Sunday, 12 May 2024 at 19:45:44 UTC, Ferhat Kurtulmuş wrote:

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable 
jumped out at me.

...
https://dlang.org/phobos/std_container_slist.html


This is a stack, isn't it?  LIFO?

Andy


Ahh yes. Then use dlist


What prevents ImportC from using .h directly?

2024-05-12 Thread Chris Piker via Digitalmars-d-learn

Hi D

Import D is working quite well so far.  One limitation is that 
module definitions require a tiny *.c file which is often just:

```C
#include 
```

Creating this file is trivial and has almost no knock-on effects, 
except when dealing with single file programs. I have quite a few 
small utilities with dub headers. It would be handy if I could 
set an import path and use ImportC on the header file directly, 
skipping the small C file all together.  A specific example in my 
case follows.


Given a C-lib interface defined in the header file:
```
/usr/include/cspice/SpiceUsr.h
```

it would be neat if a dub header similar to the following worked:
```d
#!/usr/bin/env dub
/+ dub.sdl:
   name "some_app"
   cImportPaths "/usr/local/include/cspice"
+/

import SpiceUsr;

// ... source continues
```

So, why does ImportC need *.c files exclusively?  I'm sure it 
solves a problem, but I don't know what that problem is.








Re: FIFO

2024-05-12 Thread Andy Valencia via Digitalmars-d-learn

On Sunday, 12 May 2024 at 19:45:44 UTC, Ferhat Kurtulmuş wrote:

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable 
jumped out at me.

...
https://dlang.org/phobos/std_container_slist.html


This is a stack, isn't it?  LIFO?

Andy



Anybody know about SDL and particularly SDL_TTF initialization?

2024-05-12 Thread WhatMeWorry` via Digitalmars-d-learn

This should be trivial, right?
I've been looking at existing D repo code for hours. Can't figure 
why TTF_Init doesn't work?

It would help if I could figure out how to use SDL_GetError()

INFO: SDL loaded v2.30.2
INFO: SDL initialized: 0
INFO: TTF loaded: v2.0.14
Error Program exited with code -1073741819


  loadSDL();
  SDL_version v;
  SDL_GetVersion();
  toStdout("SDL loaded v%d.%d.%d", v.major, v.minor, v.patch);
  auto initSDL = SDL_Init(SDL_INIT_EVERYTHING);  // returns 0 on 
success

  toStdout("SDL initialized: %d", initSDL);

  auto loadTTF = loadSDLTTF();
  SDL_TTF_VERSION();
  toStdout("TTF loaded: v%d.%d.%d", v.major, v.minor, v.patch);
  auto initTTF = TTF_Init();  // SDL must be initialized before 
calls to this library


Re: FIFO

2024-05-12 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable jumped 
out at me.  I wrote the following, but as a newbie, would be 
happy to receive any suggestions or observations.  TIA!


[...]


"next" is not a usual range primitive word in dlang. Why not just 
using slist.


Re: FIFO

2024-05-12 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote:
I need a FIFO for a work scheduler, and nothing suitable jumped 
out at me.  I wrote the following, but as a newbie, would be 
happy to receive any suggestions or observations.  TIA!


[...]

https://dlang.org/phobos/std_container_slist.html


Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2024-05-11 Thread BoQsc via Digitalmars-d-learn
A horrible alternative would be to use `alias` on `size_t` to 
make up a new pseudo-type that is more aligned with the code 
logic.


```
alias integer = size_t;
import std.stdio : writefln;

void main() {
auto arr = [
[5, 15],  // 20
[2, 3, 2, 3], // 10
[3, 6, 2, 9], // 20
];

foreach (integer i, row; arr)
{
double total = 0.0;
foreach (e; row)
total += e;

auto avg = total / row.length;
writefln("AVG [row=%d]: %.2f", i, avg);
}
}
```


FIFO

2024-05-11 Thread Andy Valencia via Digitalmars-d-learn
I need a FIFO for a work scheduler, and nothing suitable jumped 
out at me.  I wrote the following, but as a newbie, would be 
happy to receive any suggestions or observations.  TIA!


/*
 * fifo.d
 *  FIFO data structure
 */
module tiny.fifo;
import std.exception : enforce;

const uint GROWBY = 16;

/*
 * This is a FIFO, with "hd" walking forward and "tl" trailing
 *  behind:
 *tl  hd /Add here next
 *v   v
 *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
 *
 * Mildly complicated by a module-size indexing.
 */
struct FIFO(T) {
T[] items;
ulong hd, tl, length;

void
add(T t) {
// Make more room when needed
if (this.items.length == this.length) {
assert(this.hd == this.tl);

// Add room and shuffle current contents
auto olen = this.items.length;
auto newlen = olen + GROWBY;
this.items.length = newlen;
this.tl = (this.tl + GROWBY) % newlen;

// Shuffle what we're butted up against to their
//  new position at the top of this.items[]
ulong moved = olen - this.hd;
this.items[$ - moved .. $] =
this.items[this.hd .. this.hd + moved];
}

// Add item at next position
this.items[hd] = t;
this.hd = (this.hd + 1) % this.items.length;
this.length += 1;
}

// Give back next
T
next() {
enforce(this.length > 0, "next() from empty FIFO");
this.length -= 1;
auto res = this.items[this.tl];
this.tl = (this.tl + 1) % this.items.length;
return res;
}
}

unittest {
auto f = FIFO!uint();
f.add(1);
f.add(2);
f.add(3);
assert(f.next() == 1);
assert(f.next() == 2);
assert(f.next() == 3);
assert(f.length == 0);

// Now overflow several times
f = FIFO!uint();
foreach(x; 0 .. GROWBY * 3 + GROWBY/2) {
f.add(x);
}
foreach(x; 0 .. GROWBY * 3 + GROWBY/2) {
assert(f.next() == x);
}
assert(f.length == 0);
}

version(unittest) {
void
main()
{
}
}


Re: How to load a DLL file in D?

2024-05-11 Thread Lance Bachmeier via Digitalmars-d-learn

On Saturday, 11 May 2024 at 20:04:38 UTC, Lance Bachmeier wrote:

On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote:
I know that BindBC exists and otherwise would use it, but the 
bigger the library, the more extra hurdle it'll have. When I 
did a few bindings with it, I had to order the functions the 
right way, so I could do things much quicker with the 
Ctrl+Alt+Shift trick under VSCode, and even then having to 
write both a statically linked and dynamically linked version 
(the latter which required the functions to be loaded 
individually into function pointers).


Maybe I should write some automation tool...


You might find this package useful 
https://code.dlang.org/packages/dynamic


Also relevant if they're C functions: 
https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org


And this if you want to convert C headers to D code: 
https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com


Re: How to load a DLL file in D?

2024-05-11 Thread Lance Bachmeier via Digitalmars-d-learn

On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote:
I know that BindBC exists and otherwise would use it, but the 
bigger the library, the more extra hurdle it'll have. When I 
did a few bindings with it, I had to order the functions the 
right way, so I could do things much quicker with the 
Ctrl+Alt+Shift trick under VSCode, and even then having to 
write both a statically linked and dynamically linked version 
(the latter which required the functions to be loaded 
individually into function pointers).


Maybe I should write some automation tool...


You might find this package useful 
https://code.dlang.org/packages/dynamic


Re: Why is Phobos `Flag` so overthought ?

2024-05-11 Thread cc via Digitalmars-d-learn

On Thursday, 9 May 2024 at 18:48:12 UTC, Nick Treleaven wrote:
 We have a tool in our box already called `true` and that 
solves the problem.  If we had to type out the full name of 
every argument passed to every function ever written we may as 
well just adopt ObjC Cocoa style and call it 
StopWatchWithAutoStartBool().


Strawman.


Not at all.  I mean exactly that.  Why do you believe this 
function is so important it needs to have its argument type 
explicitly stated, when most functions don't?  Either that, or 
you believe all functions should.  It's arbitrary and pointless.


Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-10 Thread Andy Valencia via Digitalmars-d-learn

On Friday, 10 May 2024 at 16:33:53 UTC, Nick Treleaven wrote:
Arrays evaluate to true in boolean conditions if their `.ptr` 
field is non-null. This is bug-prone and I hope we can remove 
this in the next edition.

...
A string literal's `.ptr` field is always non-null, because it 
is null-terminated.


Thank you!

Andy


Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-10 Thread Nick Treleaven via Digitalmars-d-learn

On Friday, 10 May 2024 at 15:23:39 UTC, Andy Valencia wrote:
On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer 
wrote:
Yes, we say that a type has "truthiness" if it can be used in 
a condition (`while`, `if`, `assert`, etc).


So if I may ask for one more small clarification... WRT 
"truthiness", I've observed that empty arrays are treated as 
false, non-empty as true.


Arrays evaluate to true in boolean conditions if their `.ptr` 
field is non-null. This is bug-prone and I hope we can remove 
this in the next edition.


However, although I thought a string was basically an immutable 
array of characters, "" is treated as true, not false?


A string literal's `.ptr` field is always non-null, because it is 
null-terminated.


Re: "in" operator gives a pointer result from a test against an Associative Array?

2024-05-10 Thread Andy Valencia via Digitalmars-d-learn
On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer 
wrote:
Yes, we say that a type has "truthiness" if it can be used in a 
condition (`while`, `if`, `assert`, etc).


So if I may ask for one more small clarification... WRT 
"truthiness", I've observed that empty arrays are treated as 
false, non-empty as true.  However, although I thought a string 
was basically an immutable array of characters, "" is treated as 
true, not false?


Thanks again,
Andy



Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-10 Thread evilrat via Digitalmars-d-learn

On Friday, 10 May 2024 at 13:27:40 UTC, Dukc wrote:

Steven Schveighoffer kirjoitti 10.5.2024 klo 16.01:

On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote:
This also gets inferred as `pure` - meaning that if you use 
it twice for the same `WeakRef`, the compiler may reuse the 
result of the first dereference for the second call, without 
checking whether the referred value has changed!


This would be weak pure since the reference is mutable. This 
cannot be memoized.


The difference is the type. With a pointer parameter (both a 
bare one and one in a struct), the compiler can cache the 
result only when the pointed data is similar. However, here we 
have an integer parameter. It can be cached if it itself is 
similar to the one in the other function call. The compiler 
doesn't have to know, nor can know, when a `size_t` is a 
pointer in disguise.


This why I would just use ref counting if I were the topic 
author, trying to be smart will often comes back when one doesn't 
expect.


And as stated by previous author if the goal is to have 
self-clearable weak reference it will need some infrastructure 
anyway, so tbh this will greatly outweight any possible benefits 
of having weak refs.


Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-10 Thread Dukc via Digitalmars-d-learn

Steven Schveighoffer kirjoitti 10.5.2024 klo 16.01:

On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote:
This also gets inferred as `pure` - meaning that if you use it twice 
for the same `WeakRef`, the compiler may reuse the result of the first 
dereference for the second call, without checking whether the referred 
value has changed!


This would be weak pure since the reference is mutable. This cannot be 
memoized.


The difference is the type. With a pointer parameter (both a bare one 
and one in a struct), the compiler can cache the result only when the 
pointed data is similar. However, here we have an integer parameter. It 
can be cached if it itself is similar to the one in the other function 
call. The compiler doesn't have to know, nor can know, when a `size_t` 
is a pointer in disguise.


Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-10 Thread Steven Schveighoffer via Digitalmars-d-learn

On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote:



This also gets inferred as `pure` - meaning that if you use it 
twice for the same `WeakRef`, the compiler may reuse the result 
of the first dereference for the second call, without checking 
whether the referred value has changed!


This would be weak pure since the reference is mutable. This 
cannot be memoized.


-Steve


Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?

2024-05-10 Thread Dukc via Digitalmars-d-learn

evilrat kirjoitti 9.5.2024 klo 18.19:

```d
struct WeakRef(T) {
     private size_t _handle; // same size as a pointer

     this(T* ptr) {
     _handle = cast(size_t) ptr;
     }

     T* getRef() {
     return cast(T*) _handle;
     }

     // do the rest ...
}
```

[1] https://code.dlang.org/packages/automem


There is a hidden danger with using this struct. Since `getRef` is a 
template, it will be inferred as `pure`. Now, consider a function using it:


```D
auto derefer(WeakrefT)(WeakrefT wr) => *wr.getRef;
```

This also gets inferred as `pure` - meaning that if you use it twice for 
the same `WeakRef`, the compiler may reuse the result of the first 
dereference for the second call, without checking whether the referred 
value has changed!


You probably should add some never-executed dummy operation to `getRef` 
that prevents it from becoming `pure` if you go with this design.


Re: moving from classical lex/yacc to pegged parser

2024-05-10 Thread Dukc via Digitalmars-d-learn

Dmitry Ponyatov kirjoitti 9.5.2024 klo 11.30:
> And I also can't figure out how to inherit `ParseTree` with all my 
script language objects to get AST right from pegged parser. Should I 
use some superloop with lot of matches to process parsed `pt` tree into 
something I need myself, to drop all unneeded parsing meta info and get 
clean semantic AST?


Pegged can help you with that filtering part, at least to some extent. 
Remember you can use : and ; prefix operators in the grammar spec, and 
Pegged will drop the needless nodes for you.


Or do the reverse, use ^ prefix operator (or write a new rule) to make a 
node out of Pegged builtins.


  1   2   3   4   5   6   7   8   9   10   >