在标头中的宏中初始化结构必须在C和C ++源中都有效

时间:2011-11-02 13:21:29

标签: c++ c

struct info _info;

#define INIT(a, b, c, d)                   \
    struct info _info = {a, b, c, d}

这在C中有效,但是我得到了g ++:

  

错误:重新定义'info _info'

INIT并不总是被调用,有时_info会以其他方式初始化,这就是为什么两种方式都必须坚持下去。

上下文

我在一个用g ++编译的文件中使用INIT,但我也在gcc编译的文件中使用它。所以问题是:我需要这个头文件代码才能在两种语言中工作,无论我是在c库还是在c ++库中使用头文件。

Kerrek指出我可以使用#ifdef,所以我这样做了:

#ifndef __cplusplus

struct info _info;
#define INFO(a, b, c, d)                   \
    struct info _info = {a, b, c, d}

#else

struct info _info;
#define INFO(a, b, c, d)                   \
            _info = {a, b, c, d}
#endif

但它仍然不起作用,我得到error: ‘_info’ does not name a type 在我正在使用我的cpp项目中的宏的行: INFO("Information", 2 ,"again", 4)

2 个答案:

答案 0 :(得分:3)

在C ++中,您没有在变量声明中说struct。以下应该有效:

struct info { int x, y, z, w; };  // type definition (elsewhere in your code)

#define INIT(a, b, c, d) info _info = {a, b, c, d}

INIT(1,2,3,4);

由于变量名是固定的,因此该宏只能在任何给定范围内使用一次,这一点并不明显。为了更加灵活,我将变量名称添加到宏:

#define DECLARE_AND_INIT(var, a, b, c, d) info var = {a, b, c, d}
DECLARE_AND_INIT(my_info, 4, 5, 6, 7);

答案 1 :(得分:0)

如果记忆正确地为我服务,您可以使用typedef并避开__cplusplus特定部分。

typedef struct taginfo { int x, y, z, w; } info;
info _info;
#define INFO(a,b,c,d) _info = {(a), (b), (c), (d)}

......这应该适用于C和C ++。

请参阅Why should we typedef a struct so often in C?