If we have a const char
pointer initialized by a string literal, such as const char *str = "Hi!"
, then we cannot use str
as a compile-time constant. This makes sense, str
is a variable after all. But addresses are compile time constants, so we could use &str
just fine.
The following workaround compiles with GCC
and clang
, with -Wall
, -Wextra
, -Wpedantic
, -Weverything
(clang
only), and -std=c89
).
#include <stdio.h>
/* Bad:
* static const char *str = "Hi!";
*/
static const char str[4] = {'H', 'i', '!', '\0'};
static struct {
double x;
const char *string;
} my_struct = {1.0, str};
int main(void)
{
puts(my_struct.string);
return 0;
}
After some searching, I was unable to find something in the C
standard that would verify that this is legal and portable. My guess is that static const char str[4]
is an array, so using str
in the structs initialization is the same thing as using an address, which is a compile time constant, whereas using static const char *str
is a pointer to an array, so using it amounts to using a variable, which is not a compile time constant.
Any references to the relevant sections in the standard are greatly appreciated.
If we have a const char
pointer initialized by a string literal, such as const char *str = "Hi!"
, then we cannot use str
as a compile-time constant. This makes sense, str
is a variable after all. But addresses are compile time constants, so we could use &str
just fine.
The following workaround compiles with GCC
and clang
, with -Wall
, -Wextra
, -Wpedantic
, -Weverything
(clang
only), and -std=c89
).
#include <stdio.h>
/* Bad:
* static const char *str = "Hi!";
*/
static const char str[4] = {'H', 'i', '!', '\0'};
static struct {
double x;
const char *string;
} my_struct = {1.0, str};
int main(void)
{
puts(my_struct.string);
return 0;
}
After some searching, I was unable to find something in the C
standard that would verify that this is legal and portable. My guess is that static const char str[4]
is an array, so using str
in the structs initialization is the same thing as using an address, which is a compile time constant, whereas using static const char *str
is a pointer to an array, so using it amounts to using a variable, which is not a compile time constant.
Any references to the relevant sections in the standard are greatly appreciated.
Share Improve this question asked Feb 17 at 15:49 Ryan MaguireRyan Maguire 1078 bronze badges 4 |1 Answer
Reset to default 4You seem to be asking whether str
, having been defined as a static const char str[4]
, can be used to initialize a member of a static
structure.
C 2024 6.6 specifies constant expressions and includes:
More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:
…
— an address constant, or…
and:
An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration,…
str
is an array, not a pointer. However, in this use, it is automatically converted to a pointer to its first element. That first element is an object of static storage duration, and hence str
evaluates to a pointer to an object of static storage duration, so it may be used as an initializer.
static const char str[] = "Hi!";
to define and initialize an array of the correct size for the string literal. – Bodo Commented Feb 17 at 17:13str
is potentially reserved by the implementation for any use. – Ian Abbott Commented Feb 17 at 17:18my_struct.string
with an actual string literal"Hi!"
:static struct { … } my_struct = {1.0, "Hi!"};
. – Ian Abbott Commented Feb 17 at 17:29