2016-11-15 78 views
4

下面的代码可以编译:为什么“#define A”会干扰“namespace A {}”?

namespace A{ 
    int i; 
} 
namespace B{ 
    int i; 
} 
int main(){ return 0; } 

但是,下面的代码无法编译:

#define A 
#define B 

namespace A{ 
    int i; 
} 
namespace B{ 
    int i; 
} 
int main(){ return 0; } 

该错误信息是

error: redefinition of 'int {anonymous}::i'

后我定义AB为什么名字命名空间变成匿名的?

使用的编译器:gcc-4.9.3。

回答

13

#define A 
#define B 

namespace A{ 
    int i; 
} 
namespace B{ 
    int i; 
} 

您定义AB是什么。这意味着您的代码变为

namespace { 
    int i; 
} 
namespace { 
    int i; 
} 

预处理器运行后。由于两个名称空间都成为匿名名称空间,因此编译器会正确地抱怨您将重新声明i

请记住,当您定义预处理器将通过源代码执行的操作时,将所有出现的符号替换为您定义的任何符号。假如你做了

#define A LONG_NAME_I_DO_NOT_WANT_TO_TYPE 
#define B ANOTHER_LONG_NAME_THAT_I_ALSO_DO_NOT_WANT_TO_TYPE 

namespace A{ 
    int i; 
} 
namespace B{ 
    int i; 
} 

然后预处理器将改变的代码是

namespace LONG_NAME_I_DO_NOT_WANT_TO_TYPE{ 
    int i; 
} 
namespace ANOTHER_LONG_NAME_THAT_I_ALSO_DO_NOT_WANT_TO_TYPE{ 
    int i; 
} 

欲了解更多有关预处理器是如何工作的,请参阅:GCC - The C Preprocessor

+0

这是确切的原因,所有的大写常量应避免 – Slava

相关问题