I have a basic string structure:
typedef struct String {
size_t size;
union {
char *ptr, buf[sizeof(char *)];
};
} String;
The idea is to be able to extract a char * from a String like so:
extern String string;
char *str = string.size >= sizeof(char *) ? string.ptr : string.buf;
I have a problem. What if I have a const static/global String struct that has to be initialized at compile time? What if I do not want to just hardcode the assumption that char * is of a given size?
static const String string = {
sizeof(CONSTANT_STRING)-1,
#if sizeof(CONSTANT_STRING) > sizeof(char *)
.name
#else
.buf
#endif
= CONSTANT_STRING
But as we know sizeof() happens after preprocess time so cannot be used in an #if.
How can I conditionally assign either one member of my string or another to a given value at compile time so the resulting expression is a compile time constant?
Disclaimer: This answer requires C23 to work reliably
In order for the compound literals to be guarinteed compile-time constants they have to be specified as
constexprwhich is a C23-specific feature. Otherwise withoutconstexprthis may or may not work depending on the compiler and its interpretation of the standard.This could be done but I had to redesign the
Stringstructure. Instead of having an unnamed nested union, I could have a named union member and conditionally initialize it to different compound literals using the?:operator: