简体   繁体   中英

Static initialization of array of struct A, where struct A contains a pointer to array of struct B (in C)

Given the following typedefs:

// Structures for kana to romaji conversion lookup
typedef struct {
  const u16 kana; // Kana codepoint
  const char* romaji;
} KanaSuffix;

typedef struct {
  // Kana codepoint is implied by position in array
  const char* romaji;
  const KanaSuffix* suffixes;
} KanaPrefix;

Is it possible to initialize an array of KanaPrefix statically in a single step, where some elements of the array have suffixes pointing to a static array of KanaSuffix ?

Now I'm doing this:

const KanaSuffix KANA_SUFFIXES_KI[] = {
  { 0x3030, "kya" },
  { 0x3032, "kyo" }
};

const KanaPrefix KANA_TO_ROMAJI[] = {
  { NULL, NULL },
  { "a", NULL },
  { "ki", KANA_SUFFIXES_KI }
};

But I want to do something more like this:

const KanaPrefix KANA_TO_ROMAJI[] = {
  { NULL, NULL },
  { "a", NULL },
  { "ki", {
    { 0x3030, "kya" },
    { 0x3032, "kyo" }
  } }
};

You can do something like:

const KanaPrefix KANA_TO_ROMAJI[] = {
  { NULL, NULL },
  { "a", NULL },
  { "ki",  (KanaSuffix [2]) {
      { 0x3030, "kya" },
      { 0x3032, "kyo" }
    }
  }
};

EDIT :

I can [now] confirm this is defined behaviour, since the lifetime [or duration] of that compound literal is the same as of static storage:

C99 §6.5.2.5 Compound literals

The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function , the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

References:

What is the lifetime of compound literals passed as arguments?

If all you need is a static object, then you can use compound literals, since if defined outside of a function scope, have static storage duration.

Of course since the member suffixes of the struct KanaPrefix is pointing to more than one element you will need to store the count too:

typedef struct {
  const char* romaji;
  const KanaSuffix* suffixes;
  const size_t count;   
} KanaPrefix;

const KanaPrefix KANA_TO_ROMAJI[] = {
  { NULL, NULL , 0 },
  { "a", NULL , 0 },
  { "ki", ( KanaSuffix[2] ){ //this is a compound literal
    { 0x3030, "kya" },
    { 0x3032, "kyo" }
  } , 2 }  //count is here
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM