C语言 为什么从 sizeof 赋值会改变从 size_t 赋值到 int 的变量类型



该程序编译时没有警告,并提供预期的输出。

#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如何导致某些隐式类型强制转换intsizeof运算符的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有关。

最新更新