I have some C99 code that looks like this:
struct foo {
char* buf;
size_t buf_sz;
};
struct foo list[3];
list[0].buf = "The first entry";
list[0].buf_sz = strlen(list[0].buf);
list[1].buf = "The second entry";
list[1].buf_sz = strlen(list[1].buf);
list[2].buf = "The third entry";
list[2].buf_sz = strlen(list[2].buf);
Is there a shorthand way of writing this in an initializer list? Is something like this safe?
struct foo list[] = {
{ "The first entry", strlen(list[0].buf) },
{ "The second entry", strlen(list[1].buf) },
{ "The third entry", strlen(list[2].buf) }
};
How about this one:
I
#undef
ed the macro right after the initialiser. Such short names should be used in a compact&short piece of code only. If you want to use it elsewhere, use a self-explanatory name (it should include the name of thestruct
type) and remove the#undef
.Note this only works with a string literal. But it works at file-level and does not introduce any run-time overhead. Thus it also works for
const struct list[]
, i.e. a constant array.Be cautious about the
sizeof(str) - 1
. This is the same asstrlen
yields, but the allocated memory is actuallysizeof(str)
.Try
Please note that the size is set to
strlen(STR1) + 1
, due to the "string"'s0
-terminator. To adjust this doYou cannot use your second definition for a static duration
foo
array, because initializer lists for static duration objects are required to be constant. Draft n1256 for C99 states in 6.7.8 Initialization §4Even for automatic (block scope)
foo
arrays it is unspecified by the standard whether your second syntax is valid or undefined behaviour. Item §23 of same paragraph saysand note 133 precises:
That means that if would be acceptable for a compiler implementation to initialize the
buf_sz
members before thebuf
members which would lead to UB (even if it gives correct result without any warning on my old MSVC2008).For that reasons my advice is to initialize only the
buf
members, and then use a loop to set thebuf_sz
members that require the structs to be already initialized - as a side effect, if can be used the same for static or dynamic storage duration:and later in code:
One alternative would be:
If you need to put in the number of actual bytes consumed by the string, then you'd need a
+1
on yourstrlen
. I don't know what the API requires.