【问题标题】:What does typedef with no type mean?没有类型的 typedef 是什么意思?
【发布时间】:2018-11-28 05:16:12
【问题描述】:

来自标准N1570 6.7.8:

typedef 声明没有引入新类型,只是一个同义词 对于如此指定的类型。

所以我预计不可能写出这样的东西:

typedef t;
t *t_ptr;

并且它应该无法编译,因为没有类型可以引入提供的同义词。但没关系:Demo。那么这意味着什么以及它为什么会编译?

【问题讨论】:

  • 它就像 MSVC 是一个很好的 C 编译器一样好,即一点也不好。

标签: c typedef


【解决方案1】:

这依赖于这样一个事实,即缺少类型规范默认为int。

所以,你的陈述

 typedef t;

与

相同
 typedef int t;

使用适当的警告级别,编译器会发出警告:

warning: type defaults to ‘int’ in declaration of ‘t’ [-Wimplicit-int]
 typedef t;
         ^

也就是说,不要依赖这种行为,“隐式 int”规则自 C99 以来已过时。

【讨论】:

  • 这么有理由问它是否标准化?
  • @SomeName 是 3 年前的事,现在已经 2 年没有了。
  • @AnttiHaapala 那么现在行为是未定义还是实现已定义?
  • @SomeName 也没有。 C99、C11、C17 编译器必须将此诊断为不正确的程序。
  • @SomeName 对隐式 int 的支持本身已被删除,尽管它仍作为编译器扩展提供。使用严格模式,你的代码首先应该编译失败。
【解决方案2】:

默认为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 来迷惑读者,并不是每个人都知道标准的适用性。 :)
  • 我确实提到它从 C99 开始不相关。但我可以说得更清楚。
  • 如果您移动两个块的位置,我将不胜感激。 首先,提及 C99/C11,然后提及 C89。只是我的两分钱。
  • @SouravGhosh:完成。
【解决方案3】:

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;

您引用的来源中还有更多示例。

【讨论】:

  • 这很好,但这如何回答这个问题?
  • @Sourav Ghosh 我觉得typedef 语法对他来说是新的,所以我给他一些cmets 的基本示例。其他答案本身已经解决了编译问题。
  • 请不要发明自己的术语和语法,这些术语和语法甚至在 C 语言中都不存在。没有称为“基本类型”或“类型别名”的语法项。
  • @Lundin。谢谢。我应该指定 base-type 和 type-alias 应该被实际类型和名称替换。此外,伪语法不适合函数类型。我还将 alias 更改为 synonym,因为 C 标准引用 typedef 名称。
猜你喜欢
  • 1970-01-01
  • 2011-04-28
  • 2023-03-10
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2017-07-05
  • 1970-01-01
相关资源
最近更新 更多