#Why does this error with "initializer element is not a compile-time constant"?

50 messages · Page 1 of 1 (latest)

dusty temple
#

I know that const != constant, but I haven't been able to figure out why static int *foo = {(int []){42}}; in the below program prints the error initializer element is not a compile-time constant with both gcc and clang. I've tried a bunch of stuff on godbolt, but haven't been able to figure out the answer.

inland bearBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

dusty temple
#

;compile -Wall -Wextra -Werror -Wpedantic -g -fsanitize=address,undefined

int main(void) {
    static int *foo = {(int []){42}};
    (void)foo;
}
stone forgeBOT
#
Compiler Output
<source>: In function 'main':
<source>:2:24: error: initializer element is not constant
    2 |     static int *foo = {(int []){42}};
      |                        ^
<source>:2:24: note: (near initialization for 'foo')
Build failed
bold frost
#

try constexpr on c2x

dusty temple
# bold frost try constexpr on c2x

;compile -Wall -Wextra -Werror -Wpedantic -g -fsanitize=address,undefined -std=c2x

int main(void) {
    static constexpr int *foo = {(int []){42}};
    (void)foo;
}
stone forgeBOT
#
Compiler Output
<source>: In function 'main':
<source>:2:34: error: initializer element is not constant
    2 |     static constexpr int *foo = {(int []){42}};
      |                                  ^
<source>:2:34: note: (near initialization for 'foo')
Build failed
mild sierra
#

static variables can only use initialisers that are constant expressions.

#

A compound literal like that unfortunately does not fall into that category.

bold frost
#

can you not constexpr them ?

mild sierra
#

No.

#

Oh well, not the constexpr they did there at least.

dusty temple
bold frost
#

yea doesnt seem to work

mild sierra
#

Only available from 2023 though.

dusty temple
mild sierra
#

No.

#

Maybe I would question whether it has to be a pointer there.

dusty temple
#

In practice instead of an int it was an array of char *

mild sierra
#

Then you can use a string literal.

#

But a normal array declaration seems to work as well.

#

const char *const presets[] = {"LOW", "MID", "HIGH"}; works.

dusty temple
#

;compile -Wall -Wextra -Werror -Wpedantic -g -fsanitize=address,undefined -std=c2x

struct s {
  char **arr;
};

int main(void) {
    static struct s foo = {.arr=(char *[]){"a", "b"}};
    (void)foo;
}
stone forgeBOT
#
Compiler Output
<source>: In function 'main':
<source>:6:33: error: initializer element is not constant
    6 |     static struct s foo = {.arr=(char *[]){"a", "b"}};
      |                                 ^
<source>:6:33: note: (near initialization for 'foo.arr')
Build failed
dusty temple
#

Where consting it doesn't seem to fix it:

#

;compile -Wall -Wextra -Werror -Wpedantic -g -fsanitize=address,undefined -std=c2x

struct s {
  char const *const *const arr;
};

int main(void) {
    static struct s const foo = {.arr=(char const *const []){"a", "b"}};
    (void)foo;
}
stone forgeBOT
#
Compiler Output
<source>: In function 'main':
<source>:6:39: error: initializer element is not constant
    6 |     static struct s const foo = {.arr=(char const *const []){"a", "b"}};
      |                                       ^
<source>:6:39: note: (near initialization for 'foo.arr')
Build failed
dusty temple
#

Sorry for not giving this info before, I didn't realize that my minimal example was too minimalized

mild sierra
#

You can declare the array as another static variable.

tropic obsidian
#

;compile -Wall -Wextra -Werror -Wpedantic -g -fsanitize=address,undefined

static int *foo = {(int []){42}};
int main(void) {
    (void)foo;
}
stone forgeBOT
#
Compilation successful

No output.

tropic obsidian
#

this works fine

#

;compile -Wall -Wextra -Werror -Wpedantic -g -fsanitize=address,undefined -std=c2x

int main(void) {
    static int *foo = {(static int []){42}};
    (void)foo;
}
stone forgeBOT
#
Compilation successful

No output.

tropic obsidian
#

also in C2X this is valid

tropic obsidian
mild sierra
#

Uhm... that was not what I was talking about.

tropic obsidian
mild sierra
#

That it's not a constant expression.

tropic obsidian
#

it is a valid constant expression, you just can't use the value of it

dusty temple
#

And any clue why it's valid in c2x? They just made the rules more lenient?

tropic obsidian
dusty temple
#

Tyvm!

#

!solved