繁体   English   中英

C中的同义词`typedef`是可互换的吗?

[英]Are synonymous `typedef`s in C interchangable?

声明qboolean SNDDMA_InitDirect (void); 出现在第69行的'WinQuake / snd_win.c'中 但是, 函数的定义(出现在同一文件的第183行写为:

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

qbooleansndinitstat都是枚举的typedefsndinitstat'WinQuake / snd_win.c'的第33行

typedef enum {SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL} sndinitstat;

qboolean'WinQuake / COMMON.H'(第30行)

typedef enum {false, true} qboolean;

这些是不同的枚举

我一直在使用Visual Studio 2015的内置编译器( cl.exe )和Clang v3.7.1通过Visual Studio的LLVM插件编译此源代码。 Clang说声明/定义的这种差异是错误的。 Visual Studio编译好了。 谁是对的?

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

  • 5.5枚举类型 (第127页)

    枚举常量在定义类型时指定,其类型为int

  • 5.10节“ Typedef名称” (第149页)

    使用typedef存储说明符的声明不会引入新类型; 对于可以通过其他方式指定的类型,名称被视为同义词。

这两段对我来说就好像Clang的错误虽然有用但根据标准不正确。 但我知道微软在正确编译C方面没有最大的声誉。

它们引用了不同的枚举:

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

根据6.2.5:16,

每个不同的枚举构成不同的枚举类型。

所以Clang肯定是正确的。

如果隐藏在typedef名称后面的枚举类型qbooleansndinitstat兼容的 ,那么代码就可以了。 如果它们不兼容 ,则代码是错误的。 (参见6.2.7兼容型和复合型 )。

如果两个函数声明都存在于同一个转换单元中,那么返回类型兼容性要求对于类型必须相同的点变得更加严格。

在您的情况下,两个无标记枚举类型用于定义这些typedef名称。 枚举声明完全不同,使它们不兼容 这意味着有问题的代码确实包含错误,Clang是抱怨的权利。 Visual Studio错过了此错误。

请注意,虽然Clang(以及GCC)将它带到另一个极端 - 即使没有,它们也会报告错误。 例如,这些声明

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM