No, you cannot use index access to struct data members, unless you take specific steps to emulate it.
In C++ this functionality can be emulated by using a C++-specific pointer type known as "pointer-to-data-member". C language has no such type, but it can in turn be emulated by using the standard offsetof
macro and pointer arithmetic.
In you example it might look as follows. First, we prepare a special offset array
const size_t TW_OFFSETS[] =
{ offsetof(TWO_WORDS, string1), offsetof(TWO_WORDS, string2) };
This offset array is later used to organize index access to struct members
*(char **)((char *) &tw + TW_OFFSETS[i]);
/* Provides lvalue access to either `tw.string1` or `tw.string2` depending on
the value of `i` */
It doesn't look pretty (although it can be made to look better by using macros), but that's the way it is in C.
For example, we can define
#define TW_MEMBER(T, t, i) *(T *)((char *) &(t) + TW_OFFSETS[i])
and use it in the code as
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));
Note that this approach is free from the serious issues present in the solution based on reinterpreting the struct as char*[2]
array (regradless of whether it is done through a union or through a cast). The latter is a hack, illegal from the formal point of view and generally invalid. The offsetof
-based solution is perfectly valid and legal.