在C99之前,如果您没有指定类型,则会隐含使用int,这就是您代码中出现的情况。实际上,即使在C99模式下,gcc
和clang
也只会产生警告。编译器警告在这种情况下是您的朋友,我在clang -Wall
中尝试了一下:
printf( "%zu\n", sizeof(const) ) ;
并且它警告我:
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
这里的所有声明:
static st;
auto au;
register reg;
volatile vl;
const cn;
同时还隐含了int类型。
我们可以看到,C99移除了隐式int的假设:
缺乏类型说明符的声明不再隐含int。C标准委员会决定,让编译器诊断意外省略类型说明符比沉默地处理依赖隐式int的旧代码更有价值。实际上,编译器可能会显示警告,然后假设int并继续翻译程序。
如果我们查看草案C99标准的 Forward 章节第 5 段,则包括以下内容:
[...]与上一版相比,主要变化包括:
并列出以下要点:
— 移除隐式int
更新
那么为什么sizeof
不喜欢存储类别说明符例如static和auto,但是对类型修饰符例如const和volatile没问题呢?这种行为似乎与声明的工作方式不一致,隐式int假设仍然有效吗?
如果我们查看标准草案中sizeof
的语法,在 draft standard 章节 6.5.3
中如下:
sizeof unary-expression
sizeof ( type-name )
因此,一个类型限定符和一个存储类说明符都不是一个表达式,但是如果我们看一下第6.7.6
节中的类型名的语法,类型限定符是一个类型名:
type-name:
specifier-qualifier-list abstract-declaratoropt
而6.7.2.1
则给出了specifier-qualifier-list的语法,具体如下:
specifier-qualifier-list:
type-specifier specifier-qualifier-listopt
type-qualifier specifier-qualifier-listopt <- Bingo allows type qualifier
因此,我们可以看出sizeof
不接受存储类修饰符,即使类型明确指定为int,所以以下内容也是错误的:
printf( "%zu\n", sizeof(static int) ) ;
而clang
告诉我们:
error: expected expression
printf( "%zu\n", sizeof(static int) ) ;
^
我们可以进一步看到,在没有()
的情况下,类型名称无法与 sizeof
一起使用:
printf( "%zu\n", sizeof int ) ;
产生了一个错误:
error: expected expression
但是,正如我之前在这里解释的那样,一元表达式可以使用()
。
auto
吗?请挑选一种语言,而不是乱试。 - crashmstrcpu register size
作为结果。 - gangadharsauto
关键字。它表示自动存储。 - peppe