C中的同义`typedefs可以互换吗?

Are synonymous `typedef`s in C interchangable?

出现在'WinQuake/snd_win.c' on line 69. However, the function's definition (appearing on line 183 of the same file中的声明qboolean SNDDMA_InitDirect (void);写成:

sndinitstat SNDDMA_InitDirect (void)
{
    /* Actual implementation is unimportant in this discussion. */
}

qbooleansndinitstat都是枚举的typedefsndinitstat 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 2015 的内置编译器——cl.exe——和 Clang v3.7.1 通过 LLVM 插件编译这个源代码Visual Studio。 Clang 声明 declaration/definition 中的这种差异是一个错误。 Visual Studio 可以编译。 谁是正确的?

现引用C:参考手册(第四版)

这两段读起来好像 Clang 的错误虽然有帮助,但根据标准是不正确的。但我知道微软在正确编译 C 方面并没有最大的声誉。

它们指的是不同的枚举:

typedef enum {false, true}  qboolean;
typedef enum {SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL} sndinitstat;

根据 6.2.5:16,

Each distinct enumeration constitutes a different enumerated type.

所以 Clang 肯定是正确的。

如果隐藏在 typedef 名称 qbooleansndinitstat 后面的枚举类型是 compatible,那么代码是可以的。如果它们不兼容,则代码是错误的。 (参见 6.2.7 Compatible type and composite type)。

如果两个函数声明出现在同一个翻译单元中,那么 return 类型兼容性要求变得更加严格,以至于类型必须 相同 .

在您的例子中,两个无标记枚举类型用于定义这些 typedef 名称。枚举声明完全不同,使它们不兼容。这意味着有问题的代码确实包含错误,而 Clang 的抱怨是正确的。 Visual Studio 漏掉了这个错误。

请注意,尽管 Clang(以及 GCC)将它带到了另一个极端 - 即使存在 none,它们也会报告错误。例如,这些声明

enum { A1, A2, A3 } foo();
enum { B1, B2, B3 } foo();

即使代码有效,也会在 Clang 和 GCC 中导致相同的错误。在此示例中,无标记枚举类型是 compatible,这足以证明声明之间 return 类型 foo 的更改是合理的。