Как переписать назначенные инициализаторы C-структуры на C89 (например, компилятор MSVC C)

ребята, у меня эта проблема:

Обычно в C99 GCC (cygwin / MinGW / linux) существует синтаксис точечной нотации для инициализаторов в C struct.
Как это:

//HELP ME HOW TO REWRITE THIS (in most compact way) to MSVC static struct my_member_t my_global_three[] = { {.type = NULL, .name = "one"}, {.type = NULL, .name = "two"}, {.type = NULL, .name = "three"}, }; 

Определив my_memeber_t в заголовке как:

 struct my_member_t { struct complex_type * type; char * name; int default_number; void * opaque; }; 

Я компилирую linux-код в MSVC 9.0 (Visual Studio 2008), на cygwin / MinGW это работает нормально.
BUT cl не может скомпилировать это (из-за error C2059: syntax error : '.' реализации C99): error C2059: syntax error : '.'

PROBLEM:
How to rewrite (many) global structs in a way that MSVC
PROBLEM:
How to rewrite (many) global structs in a way that MSVC
(resp C89) can compile it?


С наилучшими пожеланиями и благодарностью за предложения …

Несчастная реализация C99? Я не думаю, что компилятор C в VC2008 даже пытается реализовать C99. Он может занять некоторые функции, но это действительно компилятор C89 / 90.

Просто отпустите tags имени поля

 static struct my_member_t my_global_three[] = { { NULL, "one"}, { NULL, "two"}, { NULL, "three"}, }; 

В этом случае это легко, так как порядок инициализаторов в исходном коде совпадает с порядком полей в структуре. Если порядок отличается, вам придется переставить их в безцелевой версии C89 / 90.

И если это действительно ваш my_member_t , тогда вы должны либо объявить указатель строки как const char * либо прекратить инициализацию этих членов строковыми литералами.

Спасибо за вашу информацию, Нико.

Однако я обнаружил, что для структур с массивами внутри не работает. Я предлагаю эту модификацию, которая работает как на C99, так и на MSVC (проверена в MSVC ++ 2010 Express):

 #ifdef HAVE_DESIGNATED_INITIALIZERS #define SFINIT(f, ...) f = __VA_ARGS__ #else #define SFINIT(f, ...) __VA_ARGS__ #endif typedef struct { int val; int vecB[4]; int vecA[4]; } MyStruct_ts; static const MyStruct_ts SampleStruct = { SFINIT(.val , 8), SFINIT(.vecB , { 1, -2, 4, -2}), SFINIT(.vecA , { 1, -3, 5, -3}), }; 

Таким образом, вы можете использовать один файл для MSVC и других компиляторов.

 /* * Macro for C99 designated initializer -> C89/90 non-designated initializer * * Tested. Works with MSVC if you undefine HAVE_DESIGNATED_INITIALIZERS. Cscope also * groks this. * * ("SFINIT" == struct field init, but really, it can be used for array initializers too.) */ #ifdef HAVE_DESIGNATED_INITIALIZERS #define SFINIT(f, v) f = v #else #define SFINIT(f, v) v #endif struct t { char f1; int f2; double f3; }; struct tt = { SFINIT(.f1, 'a'), SFINIT(.f2, 42), SFINIT(.f3, 8.13) };