Re: constant pointer failing to compile
On Thursday, 6 April 2023 at 20:23:29 UTC, Jacob Shtokolov wrote: On Thursday, 6 April 2023 at 00:46:26 UTC, Josh Holtrop wrote: I am trying to port a small C project to D and am getting a Ah, just noticed that other people have already responded! Sorry about that! BTW, your `&data[0]` C-like pointer will also work in D's version, although it's probably a bit uglier.
Re: constant pointer failing to compile
On Thursday, 6 April 2023 at 00:46:26 UTC, Josh Holtrop wrote: I am trying to port a small C project to D and am getting a compilation error I don't understand. It seems like the compiler is just missing some type hints. Try this: ```d import std.stdio; __gshared immutable ubyte[4] data = [1, 2, 3, 4]; __gshared immutable ubyte* p = data.ptr; int main() { writeln("*p = ", *p); return 0; } ``` Look how I provided the `ubyte[4]` hint to the compiler so it thinks that it's a constant. I'm not sure why this happens, but sometimes the compiler can't deduce static arrays, especially if you're explicitly saying that they're not static (`ubyte[]`).
Re: constant pointer failing to compile
On Thursday, 6 April 2023 at 00:46:26 UTC, Josh Holtrop wrote: ``` constarrptr.d(5): Error: cannot use non-constant CTFE pointer in an initializer `cast(immutable(ubyte)*)data` ``` Why? And how can I do the equivalent to what I have been doing in C? I want these pointers to be generated at compile time, not initialized at runtime. (the full project is generating this file containing the data array (which is much longer) and multiple pointer constants to locations within it) You have 2 options: First, to use .ptr, or second, to do the initialization in static this: ```d import std.stdio; static const char[] d; static const char * p; static this() { d = [97, 98, 99]; p = &d[0]; // == d.ptr; } void main() { printf("%.*s\n", cast(int)d.length, d.ptr); writeln("*p = ", *p); }/* Prints: abc *p = a */ ``` SDB@79
Re: constant pointer failing to compile
On Thursday, 6 April 2023 at 00:59:12 UTC, Mathias LANG wrote: immutable ubyte[4] data = [1, 2, 3, 4]; Using a static array instead of a slice will do the trick. You can leave the `__gshared` if you want, but it is redundant on a global, initialized `immutable` variable. Yes, thank you, using static arrays did work. And thanks for the note on __gshared as well.
Re: constant pointer failing to compile
On 4/5/23 8:59 PM, Mathias LANG wrote: immutable ubyte[4] data = [1, 2, 3, 4]; Using a static array instead of a slice will do the trick. You can leave the `__gshared` if you want, but it is redundant on a global, initialized `immutable` variable. I found out the same thing. But I don't really understand why. the error message gives a slight clue: ``` cannot use non-constant CTFE pointer in an initializer ‘&[cast(ubyte)1u, cast(ubyte)2u, cast(ubyte)3u, cast(ubyte)4u][0]’ ``` That *isn't* a CTFE pointer, it's a pointer to a static immutable. Yes, the initialization value is a CTFE array, but the variable itself has an address. Notice how the expression has turned into an address of the initializer. I think this is a compiler bug. -Steve
Re: constant pointer failing to compile
immutable ubyte[4] data = [1, 2, 3, 4]; Using a static array instead of a slice will do the trick. You can leave the `__gshared` if you want, but it is redundant on a global, initialized `immutable` variable.
constant pointer failing to compile
I am trying to port a small C project to D and am getting a compilation error I don't understand. I've simplified the situation down to the example here. This C version compiles fine: ```c #include static const unsigned char data[] = {1, 2, 3, 4}; static const unsigned char * p = &data[0]; int main(int argc, char * argv[]) { printf("*p = %u\n", *p); return 0; } ``` My attempt to do the same in D: ```d import std.stdio; __gshared immutable ubyte[] data = [1, 2, 3, 4]; __gshared immutable ubyte * p = data.ptr; int main() { writeln("*p = ", *p); return 0; } ``` This fails to compile with gdc: ``` constarrptr.d:5:45: error: cannot use non-constant CTFE pointer in an initializer ‘&[cast(ubyte)1u, cast(ubyte)2u, cast(ubyte)3u, cast(ubyte)4u][0]’ 5 | __gshared immutable(immutable(ubyte) *) p = data.ptr; | ^ ``` And also with ldc2: ``` constarrptr.d(5): Error: cannot use non-constant CTFE pointer in an initializer `cast(immutable(ubyte)*)data` ``` Why? And how can I do the equivalent to what I have been doing in C? I want these pointers to be generated at compile time, not initialized at runtime. (the full project is generating this file containing the data array (which is much longer) and multiple pointer constants to locations within it)