#Why does this error with "initializer element is not a compile-time constant"?
50 messages · Page 1 of 1 (latest)
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.
;compile -Wall -Wextra -Werror -Wpedantic -g -fsanitize=address,undefined
int main(void) {
static int *foo = {(int []){42}};
(void)foo;
}
<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
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;
}
<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
static variables can only use initialisers that are constant expressions.
A compound literal like that unfortunately does not fall into that category.
can you not constexpr them ?
Wdym by "they did there"? Is there like an alternative?
yea doesnt seem to work
It is this:
const int *f = (constexpr int[]){42};
Only available from 2023 though.
Is there a way to make my original line compile without C23's constexpr, while keeping it a single line?
In practice instead of an int it was an array of char *
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.
Right, I forgot to mention that the idea is that I need it as a field in a static struct:
;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;
}
<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
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;
}
<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
Sorry for not giving this info before, I didn't realize that my minimal example was too minimalized
You can declare the array as another static variable.
this is because the compound literal is in block scope
;compile -Wall -Wextra -Werror -Wpedantic -g -fsanitize=address,undefined
static int *foo = {(int []){42}};
int main(void) {
(void)foo;
}
No output.
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;
}
No output.
also in C2X this is valid
you can take the address of a compound literal just fine, the issue is really just because of the lifetime of the compound literal
Uhm... that was not what I was talking about.
then what were you talking about
That it's not a constant expression.
it is a valid constant expression, you just can't use the value of it
see here
I presume the scope matters, even when the statement is marked as static, because the temporary inner compound literal isn't going to be static in block scope, but is in global scope? Very strange
And any clue why it's valid in c2x? They just made the rules more lenient?
yes
C2X allows for storage class specifiers in compound literals