digitalmars.D.learn - constant pointer failing to compile
- Josh Holtrop (44/44) Apr 05 2023 I am trying to port a small C project to D and am getting a
- Mathias LANG (3/4) Apr 05 2023 Using a static array instead of a slice will do the trick. You
- Steven Schveighoffer (13/18) Apr 05 2023 I found out the same thing. But I don't really understand why.
- Josh Holtrop (3/7) Apr 06 2023 Yes, thank you, using static arrays did work. And thanks for the
- Salih Dincer (21/31) Apr 06 2023 You have 2 options: First, to use .ptr, or second, to do the
- Jacob Shtokolov (18/20) Apr 06 2023 It seems like the compiler is just missing some type hints. Try
- Jacob Shtokolov (5/7) Apr 06 2023 Ah, just noticed that other people have already responded! Sorry
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 <stdio.h> 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)
Apr 05 2023
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.
Apr 05 2023
On 4/5/23 8:59 PM, Mathias LANG wrote: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. -Steveimmutable 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.
Apr 05 2023
On Thursday, 6 April 2023 at 00:59:12 UTC, Mathias LANG wrote:Yes, thank you, using static arrays did work. And thanks for the note on __gshared as well.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.
Apr 06 2023
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
Apr 06 2023
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[]`).
Apr 06 2023
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: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.I am trying to port a small C project to D and am getting a
Apr 06 2023