关于C#:用存储类说明符声明变量但没有类型说明符是什么意思?

What does it mean to declare a variable with a storage class specifier but no type specifier?

在阅读了ansi c c yacc语法规范之后,我注意到以下内容都是有效的:

1
2
3
4
register x;
auto y;
static z;
extern q;

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


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

1
2
3
4
5
6
7
8
9
10
11
12
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到但在这种情况下不是。

如果我们看一下C99标准草案,前面的部分会说:

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

包括以下项目符号:

— remove implicit int

更新

从国际标准编程语言的基本原理——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,但据我所知,更新后的反映c11的版本与声明中的类型说明符没有太大区别。所以这种情况下的语法不足以强制执行这个约束。您必须转到标准节6.7.2类型说明符,并看到它说:

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.