【发布时间】:2016-03-02 02:31:38
【问题描述】:
我正在一个名为 TutorialsPoint 的网站上学习 C 编程语言的基本概念。本网站上的源代码示例可以包括一个“试用”按钮,该按钮打开一个带有在线 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;
}
课程链接: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 的在线编译器却没有?
【问题讨论】:
-
这是一个警告,而不是错误。 Gcc 仍然会为你编译它。它只是超越并让您知道代码可能不正确,即使它可以编译。较小的编译器可能不会执行生成此警告所需的额外分析
-
@PeteBaughman:当然,在这种情况下,较小的编译器只会调用未定义的行为;
gcc超出预期,但按照标准,代码是错误的,并且很容易在大端架构上遇到问题,或者在将其他参数传递给printf而并非所有参数都在寄存器中传递的情况下. -
我没有意识到 GCC 仍在为我编译这段代码。这条评论回答了我的问题。我一定会注意警告并在 printf() 函数中使用正确的数据类型。
-
这是错误的,但在运行时方式是错误的,而不是编译时方式。 Gcc 正在执行额外的静态分析,但就符合标准的编译器而言,这是有效的。您在字符串中传递了错误的值,但编译器不必关心。就像除以零一样。类型检查正常,所以编译器不必关心。
-
@Olaf:这是未定义的行为,但编译器无法识别它。从符合标准的编译器的角度来看,它只是一个不透明的 C 风格字符串,后跟可变参数;
gcc特殊情况printf因为它相对容易做并且是常见的错误来源,但是符合标准的编译器不需要寻找这样的未定义行为,它是未定义的,因此他们可以尝试使其工作,或者不,或者放火烧你的房子,随他们的选择。