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

阅读ANSI C Yacc语法规范后,我注意到以下内容都是有效的:

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并继续转换程序以支持利用此function的现有源代码。

您使用的语法确实早于C99,但据我所知, 更新的新版本反映C11与声明中的类型说明符没有太大差别。 因此,这种情况下的语法不足以强制执行此约束。 您必须转到标准部分6.7.2 类型说明符,并看到它说:

每个声明中的声明说明符中应至少给出一个类型说明符,并在每个结构声明和类型名称的说明符限定符列表中给出。