2014-07-04 57 views
0

我做的事情很醜陋,但仍然有似乎有什麼東西似乎是一個錯誤..C++/CLI:解讀「VOID」爲「無效」

我有一個enum稱爲這是寫在BasicTypeIDC#

public enum BasicTypeID 
{ 
    //.. 
    FUNCTION, 
    VOID, 
    FLOAT, 
    // .. 
} 

正如我嘗試將值分配給在位置BasicTypeID數組元素:: VOID這樣的:

typedef struct TypeInfo { 
    char * name; 
    unsigned char size; 
    unsigned char sign; 
    unsigned char real; 
} TypeInfo; 

static const TypeInfo TYPE_VOID = { "void", 0, 0, 0 }; 

static TypeInfo const **basic_type_info; 

CDLLEXPORT void CLIParser_InitializeDebugInformation(char * source_folder_path, char * cdb_file_path) 
{ 
    // .. 

    int enum_size = Enum::GetNames(BasicTypeID::typeid)->Length; 

    *basic_type_info = new TypeInfo[enum_size]; 

    basic_type_info[(int)BasicTypeID::VOID] = &TYPE_VOID; // Compile error 

    VOID *dummy1; 
    FLOAT dummy2; 

    // .. 
} 

我收到的錯誤:

error C2589: 'void' : illegal token on right side of '::' 
error C2059: syntax error : '::' 

,而這是工作,如果我使用例如FUNCTION爲索引:

basic_type_info[(int)BasicTypeID::FUNCTION] = &TYPE_VOID; // Compiles without errors 

它也工作FLOAT

basic_type_info[(int)BasicTypeID::FLOAT] = &TYPE_VOID; // Compiles without errors 

這究竟是爲什麼?

+0

@ T.C .:是的,可移植性,以防Windows被移植到一個平臺,VOID應該被定義爲不同的;-)。 – rodrigo

+0

@rodrigo我認爲這是所有C編譯器一致支持'void'之前的時間。然後向後兼容性使它無法取出。 –

+0

那麼你的代碼中定義了FUNCTION和VOID在哪裏? – cup

回答

2

Windows標頭有一個#define VOID void,它混淆了你的C++/CLI代碼。

他們爲什麼這樣做?因爲早在Windows API第一次定義的那一天,C編譯器對void的支持就不統一了。由於API必須與這些編譯器一起工作,因此它在VOID中提供了它自己的版本,如果您的編譯器支持它,推測擴展到void,或者如果不支持,則提供其他類型。然後,由於向後兼容性,他們無法做任何事情。

爲什麼不使用typedef?因爲顯然當時的微軟編譯器並不認爲typedef void VOID;是合法的C(他們現在這樣做,我相信)。他們不得不保留向後兼容的宏,因爲雖然

#define VOID void 
int c(VOID){ return 0; } 

是合法的,

typedef void VOID; 
int c(VOID){ return 0; } 

不是(在C89,反正)。

幾乎所有其他Windows API類型都是typedefs而不是預處理器宏,這就是爲什麼FLOAT適合您,但VOID不適用。

+0

嗯,我認爲這可能是它,但無論什麼原因,如果我用'BasicTypeID :: FLOAT'替換'BasicTypeID :: VOID' ..這很奇怪..請參閱我的編輯 – displayname

+1

@StefanFalk'FLOAT'是一個typedef ,而不是一個宏。 –

+0

Omg我剛剛看到FLOAT是typedefed,但不是#defined ... – displayname

相關問題