c - 声明带有存储类说明符但没有类型说明符的变量是什么意思?

标签 c gcc types standards storage-class-specifier

看完ANSI C Yacc grammar之后规范我注意到以下都是有效的:

register x;
auto y;
static z;
extern q;

这对我来说似乎很奇怪,因为我对类型的理解表明这些变量都没有类型。这些是什么意思?它们是如何进行类型检查的?分配了多少内存?

最佳答案

在 C99 之前,如果未指定类型,则默认为 int 这应该在 C99 中删除,但许多编译器甚至在 C99 模式下也支持它。例如在 clang 中甚至使用 -std=c99 我只收到以下警告而不是错误:

warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  register x;
  ~~~~~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  auto y;
  ~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  static z;
  ~~~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  extern q;
  ~~~~~~ ^

gcc 在这种情况下也只提供警告,尽管使用 -pedantic-errors 标志会导致 gcc 产生错误,这是通常用于 gcc 中的扩展,通常用于 clang 但在这种情况下不是。

如果我们看一下 draft C99 standard 转发部分说:

[...]Major changes from the previous edition include:

并包括以下项目符号:

— remove implicit int

更新

来自Rationale for International Standard—Programming Languages—C 6.7.2 类型说明符部分:

new feature of C99: In C89, all type specifiers could be omitted from the declaration specifiers in a declaration. In such a case int was implied. The Committee decided that the inherent danger of this feature outweighed its convenience, and so it was removed. The effect is to guarantee the production of a diagnostic that will catch an additional category of programming errors. After issuing the diagnostic, an implementation may choose to assume an implicit int and continue to translate the program in order to support existing source code that exploits this feature.

您使用的语法早于 C99 但据我所知newer version已更新以反射(reflect) C11与声明中的类型说明符没有太大区别。所以这种情况下的语法不足以强制执行此约束。您必须转到标准部分 6.7.2 Type specifiers 并看到它说:

At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each struct declaration and type name.

关于c - 声明带有存储类说明符但没有类型说明符的变量是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21359239/

相关文章:

c - 如何重置c中分配的内存和资源?

c - GCC 寄存器优化

c - C中pid_t和int的区别

通过 fifo 队列 linux 进行通信

c++ - Astyle - 如何将不带大括号的条件格式化为 1TBS

c - Strtok 使用,代码不起作用

gcc - 尝试安装gcc-4.8.1时,使用 "Error 2"退出

objective-c - __block 属性声明

haskell - Church 风格的核心中缺少类型变量会怎样?

scala - 如何使用边界表示逆变类型参数