2014-11-24 42 views
4

將Visual Studio 2005中的項目移植到2013年時,我遇到了這種奇怪的行爲,但找不到解釋。上下文是關於通過多次包含特定頭文件來創建模板特化,但是在每個包含之前更改預處理器定義以基本上生成不同的類聲明。VS2013 - 多個包含相同標題的錯誤

我可以在問題縮小到以下情況:

gen.hpp

#ifdef ENABLE_GEN 

#ifdef GEN_SWAP_ORDER // (1) 
    class Foo {}; 
#else 
    class Bar {}; 
#endif 

#endif 

的main.cpp

#define ENABLE_GEN 

#include "gen.hpp" 
#define GEN_SWAP_ORDER 
#include "gen.hpp" 

int main() 
{ 
    Foo foo; 
    Bar bar; 
} 

可正常工作,即兩個FooBar在01中聲明並可用。

現在,造成問題,更改#ifdef中標記爲(1)#ifndef行,這應該有效只會導致其中FooBar被宣佈爲被交換的次序。而是,編譯失敗,那麼:

1>c:\path\to\main.cpp(10): error C2065: 'Bar' : undeclared identifier 
1>c:\path\to\main.cpp(10): error C2146: syntax error : missing ';' before identifier 'bar' 
1>c:\path\to\main.cpp(10): error C2065: 'bar' : undeclared identifier 

處理後的文件看起來像這樣(剝離一些空白):

#line 1 "c:\\path\\to\\main.cpp" 

#line 1 "c:\\path\\to\\gen.hpp" 

    class Foo {}; 

#line 8 "c:\\path\\to\\gen.hpp" 

#line 10 "c:\\path\\to\\gen.hpp" 
#line 4 "c:\\path\\to\\main.cpp" 

int main() 
{ 
    Foo foo; 
    Bar bar; 
} 

我的問題是:難道我失去了一些東西?這是由於某種原因的預期行爲?它是一種編譯器設置/錯誤,它使Visual Studio第二次跳過標題內容(包括#else部分),因爲它認爲它有一個標題守護(由於#ifndef)?

謝謝!

+0

這是否發生,甚至當你做一個完整的清潔+重建(以排除預編譯頭shenanigans)? – Cameron 2014-11-24 15:46:27

+4

Visual Studio包含包含守衛的優化,也許他們是越野車?有一個類似的預發佈bug:https://connect.microsoft.com/VisualStudio/feedback/details/800200/preprocessing-broken-in-vs2013 – dyp 2014-11-24 15:49:13

+1

Zinger,他們沒有完全修復這個bug。用/ showIncludes可見,你會看到文件只獲得#included一次。 – 2014-11-24 15:54:52

回答