いいえ、エミュレートするための特定の手順を実行しない限り、インデックス アクセスを使用してデータ メンバーを構造化することはできません。
C++ では、"pointer-to-data-member" と呼ばれる C++ 固有のポインター型を使用して、この機能をエミュレートできます。C 言語にはそのような型はありませんが、標準のoffsetof
マクロとポインター演算を使用してエミュレートできます。
あなたの例では、次のようになります。まず、特別なオフセット配列を用意します
const size_t TW_OFFSETS[] =
{ offsetof(TWO_WORDS, string1), offsetof(TWO_WORDS, string2) };
このオフセット配列は、後で構造体メンバーへのインデックス アクセスを整理するために使用されます。
*(char **)((char *) &tw + TW_OFFSETS[i]);
/* Provides lvalue access to either `tw.string1` or `tw.string2` depending on
the value of `i` */
見栄えはよくありませんが (マクロを使用して見栄えを良くすることはできます)、C ではそうです。
たとえば、次のように定義できます。
#define TW_MEMBER(T, t, i) *(T *)((char *) &(t) + TW_OFFSETS[i])
コードで次のように使用します
TW_MEMBER(char *, tw, 0) = "Hello";
TW_MEMBER(char *, tw, 1) = "World";
for (int i = 0; i < 2; ++i)
printf("%s\n", TW_MEMBER(char *, tw, i));
このアプローチには、構造体をchar*[2]
配列として再解釈することに基づくソリューションに存在する重大な問題がないことに注意してください (ユニオンまたはキャストのどちらを介して行われるかに関係なく)。後者はハッキングであり、正式な観点からは違法であり、一般的に無効です。offsetof
ベースのソリューションは完全に有効で合法です。