开发者

How to rewrite C-struct designated initializers to C89 (resp MSVC C compiler)

开发者 https://www.devze.com 2023-02-19 16:55 出处:网络
guys, I\'ve this problem: Normally in C99 GCC (cygwin / MinGW / linux), there is dot-notation syntax for initializers in C struct.

guys, I've this problem:

Normally in C99 GCC (cygwin / MinGW / linux), there is dot-notation syntax for initializers in C struct.

Like this:

//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, .开发者_JAVA百科name = "three"},
};

Having my_memeber_t defined in header file as:

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

I'm compiling linux code in MSVC 9.0 (Visual Studio 2008), on cygwin/MinGW this works ok.

BUT cl is unable to compile this (because of miserable C99 implementation): error C2059: syntax error : '.'

PROBLEM:

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


Best regards and thanks for suggestions...


Miserable C99 implementation? I don't think that C compiler in VC2008 even tries to implement C99. It might borrow some features, but it is really a C89/90 compiler.

Just drop the field name tags

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

In this case it is easy, since the order of the initializers in the original code is the same as the order of fields in the struct. If the order was different, you'd have to rearrange them in the tagless C89/90 version.

And if it's really your my_member_t, then you should either declare the string pointer as const char * or stop initializing these members with string literals.


Thanks for your information, Nico.

However, I have found out that for structs with arrays inside do not work. I propose this modification that works for both in C99 and MSVC (verified in 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}),
};

This way you can use one single file for MSVC and other compilers.


/*
 * 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 t t = {
    SFINIT(.f1, 'a'),
    SFINIT(.f2, 42),
    SFINIT(.f3, 8.13)
};
0

精彩评论

暂无评论...
验证码 换一张
取 消