2016-11-15 107 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

相關問題