数据类型不匹配和编译器冲突

Data Type Mismatch and Conflicting Compilers

我正在一个名为 TutorialsPoint 的网站上学习 C 编程语言的基本概念。该网站上的源代码示例可以包括一个 "try it" 按钮,该按钮使用在线 c 编译器(GNU GCC 版本 4.7.2)打开在线 c 编程环境。在一个示例中演示了 sizeof() 函数。这是源代码。

#include <stdio.h>
#include <limits.h>

int main() {

  printf("Storage size for int : %d \n", sizeof(int));

  return 0;
}

Link 上课:TutorialsPoint - C Data Types

在在线编程环境下编译执行该程序,输出结果如下:

"Storage size for int : 4"

当我尝试在我的计算机上使用 GNU GCC 5.2.1 版编译相同的代码时,我收到以下错误消息:

gcc sizeofExample.c
sizeofExample.c: In function 'main':
sizeofExample.c:6:10: warning: format '%d' expects argument of type 'int',
but argument 2 has type 'long unsigned int' [-Wformat=]
  printf("Storage size for int: %d \n", sizeof(int));
         ^

这是我的源代码,为了完整起见:

#include <stdio.h>
#include <limits.h>

int main()
{
  printf("Storage size for int : %d \n", sizeof(int));

  return 0;
}

我知道这个错误是由于 %d [int 数据类型] 和 sizeof(int) [long unsigned int] 之间的数据类型不匹配造成的。

为什么我的编译器检测到数据类型不匹配,而 TutorialsPoint 的在线编译器却检测不到?

Why does my compiler detect a data type mismatch

因为 printf 期望 %zu(而不是 %dsizeof(type)

sizeof 产生 size_t 结果(无符号数,在 32 位系统上通常为 4 个字节,在 64 位系统上通常为 8 个字节)。您应该使用适当的 printf 格式代码,在本例中为 %zuz 表示 "width equivalent to size_t",u 表示 "unsigned value")。这应该在所有系统上都能正常工作(除了极少数不支持 z 大小修饰符的非常古老的系统)。

在线编译器可能不会抱怨,因为:

  1. 它没有执行深入的 printf 格式代码检查 gcc
  2. 它是一个 32 位编译器,size_tint 的大小相同(尽管符号不同),所以没有大小不匹配,而你的本地 gcc 是 64 位编译器,大小不同。
  3. 编译器根本不显示警告,以便为初学者保持输出简单。

注意gcc只是警告,不是报错,所以代码会编译完成,运行。不过,警告通常表示存在问题,因此最好进一步调查。

这是警告而非错误,因此编译正在完成并生成可执行文件,但 GCC 警告您可能会导致不良行为。至于为什么TutorialPoint不显示这个警告,一个类似的在线编译器网站ideone.comalso doesn't throw this warning. You can see here说Ideone使用的是GCC编译器。在线网站通常会抑制警告以简化用户的输出。修复警告总是一个好主意,在这种情况下,您可以使用:

printf("Storage size for int : %zu \n", sizeof(int));

这可能会为您节省 未定义行为 因不匹配 printf 类型读取更多内存而导致的问题。阅读更多相关信息 here