我正在做一些非常丑陋的事情,但是似乎有些东西似乎是一个错误..
我有enum
名为BasicTypeID
,用 C#编写:
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 :(得分:2)
Windows标头有#define VOID void
,这会混淆您的C ++ / CLI代码。
他们为什么这样做?因为在第一次定义Windows API的那天,对void
的C编译器支持并不统一。由于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类型都是typedef而不是预处理器宏,这就是为什么FLOAT
适合您但VOID
没有。