【发布时间】:2018-11-28 05:16:12
【问题描述】:
来自标准N1570 6.7.8:
typedef声明没有引入新类型,只是一个同义词 对于如此指定的类型。
所以我预计不可能写出这样的东西:
typedef t;
t *t_ptr;
并且它应该无法编译,因为没有类型可以引入提供的同义词。但没关系:Demo。那么这意味着什么以及它为什么会编译?
【问题讨论】:
-
它就像 MSVC 是一个很好的 C 编译器一样好,即一点也不好。
来自标准N1570 6.7.8:
typedef声明没有引入新类型,只是一个同义词 对于如此指定的类型。
所以我预计不可能写出这样的东西:
typedef t;
t *t_ptr;
并且它应该无法编译,因为没有类型可以引入提供的同义词。但没关系:Demo。那么这意味着什么以及它为什么会编译?
【问题讨论】:
这依赖于这样一个事实,即缺少类型规范默认为int。
所以,你的陈述
typedef t;
与
相同 typedef int t;
使用适当的警告级别,编译器会发出警告:
warning: type defaults to ‘int’ in declaration of ‘t’ [-Wimplicit-int]
typedef t;
^
也就是说,不要依赖这种行为,“隐式 int”规则自 C99 以来已过时。
【讨论】:
默认为int。
编译器警告显示发生了什么:
#1 with x86-64 gcc 8.2
<source>:1:9: warning: type defaults to 'int' in declaration of 't' [-Wimplicit-int]
typedef t;
从 C99 开始,隐式 int 规则已被删除。所以这不适用于 C99 以后。
如果您在 GCC 中使用 -pedantic-errors 编译器选项(意味着严格符合标准),会发出错误。见here。
如果您有兴趣,C89 标准中的relevant section 允许这样做:
3.5.2 类型说明符
每个类型说明符列表应为以下集合之一;类型说明符可以以任何顺序出现,可能与其他声明说明符混合。
- 无效
- 字符
- 签名字符
- 无符号字符
- short 、signed short 、short int 或signed short int
- unsigned short 或 unsigned short int
- int 、signed 、signed int 或无类型说明符
所以在 C99 中,上面加粗的最后一部分(或没有类型说明符)被删除了。
【讨论】:
C89 来迷惑读者,并不是每个人都知道标准的适用性。 :)
typedef 声明定义了对象或指针类型的同义词。因此,您应该指定要为其创建同义词的类型和用作同义词的名称。
例如:
// 'byte_t' is a synonym for 'unsigned char'
typedef unsigned char byte_t;
// 'handler_t' is a synonym for 'void (*)(int)', a function pointer
typedef void (*handler_t)(int);
// 'short_p' is a synonym for 'short *'
typedef short * short_p;
// 'record' is a synonym for an anonymous structure
typedef struct {
int a;
char *b;
} record;
// 'error_p' is a synonym for a pointer to 'struct error', defined somewhere else
typedef struct error *error_p;
您引用的来源中还有更多示例。
【讨论】:
typedef 语法对他来说是新的,所以我给他一些cmets 的基本示例。其他答案本身已经解决了编译问题。
base-type 和 type-alias 应该被实际类型和名称替换。此外,伪语法不适合函数类型。我还将 alias 更改为 synonym,因为 C 标准引用 typedef 名称。