【发布时间】:2016-02-05 23:20:02
【问题描述】:
声明qboolean SNDDMA_InitDirect (void); 出现在'WinQuake/snd_win.c' on line 69 中。但是,function's definition (appearing on line 183 of the same file 写为:
sndinitstat SNDDMA_InitDirect (void)
{
/* Actual implementation is unimportant in this discussion. */
}
qboolean 和 sndinitstat 都是枚举的typedefs:sndinitstat on line 33 of 'WinQuake/snd_win.c',
typedef enum {SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL} sndinitstat;
和qboolean 在'WinQuake/common.h' (line 30)
typedef enum {false, true} qboolean;
这些是不同的枚举。
我一直在通过 Visual Studio 的 LLVM 插件使用 Visual Studio 2015 的内置编译器 -- cl.exe -- 和 Clang v3.7.1 编译此源代码。 Clang 声明这种声明/定义的差异是一个错误。 Visual Studio 编译这个没问题。 谁是正确的?
现在引用C: A Reference Manual (Fourth Edition):
-
第 5.5 枚举类型(第 127 页)
枚举常量在定义类型时指定,类型为
int。 -
第 5.10 类型定义名称(第 149 页)
带有
typedef存储说明符的声明不会引入新类型;这些名称被认为是可以以其他方式指定的类型的同义词。
这两段在我听来好像 Clang 的错误虽然有帮助,但根据标准是不正确的。但我知道微软在正确编译 C 方面的声誉并不高。
【问题讨论】:
-
他们是
typedefs 的同一个枚举列表吗?或者换一种说法,你应该在问题中添加qboolean和sndinitstat的定义。 -
C 标准解释的不一致在编译器之间并不少见。在我的编译器中,即使设置为最严格的设置,也不会将同一类型的不同别名识别为错误。在我看来,任何编译器最多应该将其标记为警告,而不是错误。
-
我在链接中找到了
typedef enum {SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL} sndinitstat;。你可以访问qboolean的 typedef 吗?它在链接中被引用,但它的定义可能在其中一个头文件中。 -
@user3386109 - 如果两个别名的枚举相同,则需要 redeclaration 编译器错误。枚举必须完全不同。
-
因为 Visual Studio 将匿名枚举视为类型
int。所以 typedef 等价于typedef int qboolean和typedef int sndinitstat。因此,Visual Studio 认为qboolean和sndinitstat是同一类型。常识(和叮当声)说这是非常错误的。语言律师如何解释规范是有争议的,但有点毫无意义。如果对规范的正确解释表明 Visual Studio 是正确的,那么这只是意味着该规范大错特错。
标签: c visual-studio clang typedef