1

我有一个预处理器宏,它根据宏参数生成函数和变量。

用 A 依次调用宏,B 宏会生成类似

Inst* AActivate() { ... }
bool Atemp;

Inst* BActivate() { ... }
bool Btemp;

由于宏是在头文件中定义的,因此我收到链接器错误,通知我有关已定义的符号。我曾经使用过#pragma,但我想问题在于在标头中实现函数。

这是宏:

    #define REGISTER(ns, id, type) \
        Inst* type##Activate() { return new type(); }\
        bool type##temp = RegisterType(ns << 8 | id, &type##Activate);

现在我想知道如何处理这些问题。我的第一个想法是使用一些#define-Guards,但显然这需要嵌套的#defines,这在 C++ 中是不可能的。我阅读了有关 boost 的可能解决方案,但不幸的是,我无法使用这些库。

任何的想法?

先感谢您...

4

3 回答 3

3

您的宏在标头中生成函数定义,并且与任何普通函数一样,如果标头包含在多个翻译单元中,则标头中的非内联函数会违反 ODR。因此,只需将生成的函数内联即可。

对于 ODR 也适用的全局变量,您必须将它们声明为 static 或 const 以获得内部链接。反过来,这将为您提供变量的多个独立实例,每个翻译单元对应一个包含标题的翻译单元。无论如何,全局变量被认为是不好的风格,所以也许你应该想点别的。

于 2013-08-30T09:44:34.943 回答
0

Use the macro in a .cpp file or inline the functions. It doesn't really help that you use #pragma once because that only stops the header from being included more than once per .cpp file. When you compile several .cpp files, the functions get defined several times.

于 2013-08-30T09:44:54.033 回答
0

You tagged for both, C and C++, you really should decide which one you use.

Things like that can only work (in both languages) if you have the function definitions as inline. You'd then have to have two macros, one for the inline definition that you would call in every header file that is to see the function.

In addition you'd have to have a second macro that is only called in one .c or .cpp file to do the "instantiation" for you. Here the syntax may be a bit different for C or C++.

In C this should look something like

    #define REGISTER(ns, id, type)                                          \
       inline Inst* type##Activate() { return new type(); }                 \
       extern bool type##temp

    #define INSTANTIATE(ns, id, type)                                       \
       Inst* type##Activate();                                              \
       bool type##temp = RegisterType(ns << 8 | id, &type##Activate)
于 2013-08-30T09:47:59.213 回答