Re: need help to use C++ callback from garnet
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.
How to pass in reference a fixed array in parameter
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: How to pass in reference a fixed array in parameter
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.
Re: How to pass in reference a fixed array in parameter
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
bool passed by ref, safe or not ?
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*)&a; 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: bool passed by ref, safe or not ?
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*)&a; 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 &a 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.
Re: bool passed by ref, safe or not ?
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*)&a; 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 ?
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*)&a; 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*)&a` 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 ?
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 ?
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 ?
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: How to pass in reference a fixed array in parameter
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(&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(&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 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.