该程序编译时没有警告,并提供预期的输出。
#include <stdio.h>
#include <stddef.h>
int i;
size_t s = sizeof(i);
int main(void){
printf("%zu n", s);
}
但是这个程序不编译,我观察到以下警告和错误:
#include <stdio.h>
#include <stddef.h>
int i;
size_t s;
s = sizeof(i);
int main(void){
printf("%zu n", s);
}
警告和错误:
$ gcc -std=c99 -o sizeof_test sizeof_test.c
sizeof_test.c:6:1: warning: data definition has no type or storage class [enabled by default]
s = sizeof(i);
^
sizeof_test.c:6:1: warning: type defaults to ‘int’ in declaration of ‘s’ [enabled by default]
sizeof_test.c:6:1: error: conflicting types for ‘s’
sizeof_test.c:5:8: note: previous declaration of ‘s’ was here
size_t s;
^
sizeof_test.c: In function ‘main’:
sizeof_test.c:9:5: warning: format ‘%zu’ expects argument of type ‘size_t’, but argument 2 has type ‘int’ [-Wformat=]
printf("%zu n", s);
^
以下是gcc
版本信息:
$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
我的理解是,至少对于 c99 甚至更早,sizeof
的返回类型为 size_t
,例如在 cpp首选项中所述。
如果是这样,当某些隐式类型转换不是作为size_t
变量的直接初始化时,sizeof
如何导致某些隐式类型强制转换int
?sizeof
运算符的s
和返回类型都不int
,那么int
类型从何而来?
问题是您只能在全局范围内使用变量定义(带有可选的初始值设定项(。 不能有可执行语句。
当编译器在全局范围内看到此问题时:
s = sizeof(i);
由于语句不能存在于那里,因此它假定它是一个变量声明。 您收到的错误和警告如下:
- 由于声明未定义类型,因此类型默认为
int
,您会收到这两者的警告。 - 然后,您会收到冲突类型的错误,因为此隐式定义的
int
与上一行上定义的size_t
具有相同的名称。 - 有关无效
printf
格式说明符的警告也随之而来,因为s
的最新定义是int
。
真正的问题是,你不能在所有函数之外分配变量。
size_t s;
s = sizeof(i);
这两行被解释为:一个全局变量s
类型为 size_t
,另一个全局变量s
隐式类型为 int
(在 C99 中无效(,并用 sizeof(i)
初始化。
如果您了解这一点,则可以理解所有错误/警告消息。它们要么与s
的隐式int
类型有关,要么与定义了两种不同类型的s
有关。