Can I reduce the long initialization of an array to a short list of initializers in C?

I have a 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 to write this to the 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) }
};
+1
source share
4 answers

One of the options:

struct foo {
    char* buf;
    size_t buf_sz;
};

...

struct foo list[] = {
    { "The first entry" },
    { "The second entry" },
    { "The third entry" }
};

...

for ( int i = 0; i < sizeof(foo)/sizeof(foo[0]); i++ )
    list[i].buf_sz = strlen(list[i].buf); // number of chars in string

If you need to specify the number of actual bytes consumed by the string, then you will need +1on yours strlen. I do not know what the API requires.

+3
source

How about this:

#define S(str)  { str, sizeof(str) - 1 }
struct foo list[] = {
    S("The first entry"),
    ...
};
#undef S

I #undef . . , ( struct) #undef.

, . . , const struct list[], .. .

sizeof(str) - 1. , strlen, sizeof(str).

+5

Try

#define STR1 "The first entry"

struct foo list[] = {
  {STR1, sizeof STR1},
  ...

, strlen(STR1) + 1, - "string" 0 -terminator. ,

struct foo list[] = {
  {STR1, sizeof STR1 - 1},
  ...
+3

foo, . n1256 C99 6.7.8 §4

4 .

() foo , undefined. §23 :

23 , - , unspecified.133)

133:

,

, buf_sz buf, UB ( MSVC2008).

, buf, buf_sz, , , - , :

struct foo list[] = {
    { "The first entry" },
    { "The second entry" },
    { "The third entry" }
};

:

int i;
for(i=0; i<sizeof(foo)/sizeof(foo[0]); i++) {
    foo[i].buf_sz = strlen(foo[i].buf);
}
+3

Source: https://habr.com/ru/post/1662307/


All Articles