Reputation: 107
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.
Upvotes: 2
Views: 76
Reputation: 223795
You 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.
Upvotes: 4