阅读完 ANSI C Yacc语法规范 后,我注意到以下所有内容都是有效的:
register x;
auto y;
static z;
extern q;
对我来说,这似乎很奇怪,因为我对类型的理解表明这些变量都没有类型。那么这些是什么意思?它们如何进行类型检查?分配了多少内存?
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
,但不包括此情况。
如果我们查看C99标准草案中的前言部分,它说:
[...]与上一版相比的主要变化包括:
并包括以下要点:
— 删除隐式int
更新
从C语言国际标准编程语言的解释第6.7.2
节类型说明符中得知:
C99的新特性:在C89中,声明中的声明说明符可以省略所有类型说明符。在这种情况下,隐含的是int。委员会认为,这一特性的固有危险权衡了其方便性,因此删除了它。其效果是保证生成将捕获程序错误的诊断信息。在发出诊断后,实现可以选择假定隐式int并继续翻译程序,以支持利用此特性的现有源代码。
您使用的语法先于C99,但据我所知,已针对C11更新的新版本在声明中的类型说明符方面并没有太大差异。因此,在这种情况下,该语法不足以强制执行此约束条件。您必须转到标准部分6.7.2
类型说明符,并查看其内容:
在每个声明的声明说明符中,以及在每个结构声明和类型名称的说明符修饰符列表中,都必须给出至少一个类型说明符。
int
。 - Joseph Quinseyunsigned w
。我在一个广泛使用这种习惯用法的代码库中工作。 - StilesCrisis