【发布时间】:2019-08-06 12:28:51
【问题描述】:
假设我有以下函数定义:
int foo () {
int x;
x = x + 2;
}
如你所见,这个函数被声明为返回一个int 值,但是没有return 语句,它也没有获取任何参数。
给定上面定义的这个函数,它构成什么类型的错误 - 语法?语义?运行 ?没有任何错误类型?
【问题讨论】:
标签: c compilation
假设我有以下函数定义:
int foo () {
int x;
x = x + 2;
}
如你所见,这个函数被声明为返回一个int 值,但是没有return 语句,它也没有获取任何参数。
给定上面定义的这个函数,它构成什么类型的错误 - 语法?语义?运行 ?没有任何错误类型?
【问题讨论】:
标签: c compilation
这不被认为是错误的语法。按照'c'标准是可以的。因此它可以编译,但结果将是不可预测的。
正如 cmets 中提到的,这只是糟糕的编程。现代编译器可以检测程序中的此类常见问题。因此,使用gcc -Wall,您可以获得以下关于缺少返回语句(控制到达...)和未初始化变量的诊断信息。
%> gcc a.c -Wall
a.c: In function 'foo':
a.c:1:1: warning: control reaches end of non-void function [-Wreturn-type]
int foo () { int x; x=x+2;}
^~~
a.c:1:22: warning: 'x' is used uninitialized in this function [-Wuninitialized]
int foo () { int x; x=x+2;}
~^~~~
a.c:1:18: note: 'x' was declared here
int foo () { int x; x=x+2;}
【讨论】:
两者都没有。如果调用者使用返回值,则它是有效的 C 但未定义的行为。 C 标准 6.9.1/12(语义)说:
如果到达终止函数的},并且函数调用的值被 调用者,行为未定义。
【讨论】:
当程序的含义与预期不符时,就是语义错误。
首先,让我们更正函数,使其初始化x:
int foo(void)
{
int x = 0;
x = x + 2;
}
其次,让我们假设函数的返回值在某处被使用。然后 C 6.9.1 12 告诉我们:
除非另有说明,否则如果到达终止函数的
},并且调用者使用了函数调用的值,则行为未定义。
如果我们进一步假设作者不打算编写具有未定义行为的程序并且没有其他东西(例如编译器实现)定义行为,那么程序foo的含义不是作者想要的——他们打算让它以某种定义的行为执行,但它没有,因此出现了错误。这是程序源代码含义的错误,是语义错误。
【讨论】: