C 中 "if" 语句的令人困惑和意外的行为
Confusing and unexpected behaviour of "if" statement in C
我在一组错误的代码示例 (http://matthieu-moy.fr/c/c_collection/) 中找到了这段代码,我研究了这些代码以提高我的编程技能。您可以看到代码、我如何执行它和下面的输出,以及我所做的一些实验。
谁能解释一下这种奇怪的现象?
代码
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return FALSE;}
int main() {
if (function_returning_false) {
printf("function returned true\n");
}
}
建造
$ gcc Bug_Example_7.c -o Bug_Example_7_gcc
执行
$ ./Bug_Example_7_gcc
输出
function returned true
结论
可以假设 'if' 条件不成立,因此程序不会打印任何内容。但显然,一个是错误的。我用 gcc (Ubuntu 9.3.0-17ubuntu1~20.04)、g++ (Ubuntu 9.3.0-17ubuntu1~20.04)、clang (10.0.0-4ubuntu1) 和在线 c 编译了这段代码编译器(https://www.onlinegdb.com/online_c_compiler),结果相同:打印输出“函数返回真值”。
进一步的实验表明:
将“FALSE”替换为“TRUE”(参见下面的代码片段)、构建、执行它,将产生相同的打印输出(“函数返回真”)。撤消更改并再次构建它并执行它不会更改输出,无论应用程序文件是否在构建之间被删除。
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return TRUE;}
int main() {
if (function_returning_false) {
printf("function returned true\n");
}
}
包含 stdbool
-library 并将定义的“FALSE”和“TRUE”替换为“false”和“true”并没有什么不同(参见下面的代码片段)。
#include <stdio.h>
#include <stdbool.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return false;}
int main() {
if (function_returning_false) {
printf("function returned true\n");
}
}
将“if”语句中的函数“function_returning_false()”替换为布尔值“false”(参见下面的代码片段),构建它,执行它,应用程序将没有打印输出,正如预期的那样。但是,如果更改之后立即撤消并再次构建和执行代码,应用程序将可以正常工作。删除应用程序并重新启动构建它的机器后,描述的现象会重新出现。
#include <stdio.h>
#include <stdbool.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return false;}
int main() {
if (false) {
printf("function returned true\n");
}
}
感谢您的宝贵时间。
您没有正确复制程序。这是重现bug的真实程序:
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return FALSE;}
int main() {
if (function_returning_false) { // note, no ()
printf("function returned true\n");
}
}
所以,它不是调用函数 - 它是将函数作为参数传递给 if
,并且在布尔上下文中,函数将始终是 true
.
我在一组错误的代码示例 (http://matthieu-moy.fr/c/c_collection/) 中找到了这段代码,我研究了这些代码以提高我的编程技能。您可以看到代码、我如何执行它和下面的输出,以及我所做的一些实验。
谁能解释一下这种奇怪的现象?
代码
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return FALSE;}
int main() {
if (function_returning_false) {
printf("function returned true\n");
}
}
建造
$ gcc Bug_Example_7.c -o Bug_Example_7_gcc
执行
$ ./Bug_Example_7_gcc
输出
function returned true
结论
可以假设 'if' 条件不成立,因此程序不会打印任何内容。但显然,一个是错误的。我用 gcc (Ubuntu 9.3.0-17ubuntu1~20.04)、g++ (Ubuntu 9.3.0-17ubuntu1~20.04)、clang (10.0.0-4ubuntu1) 和在线 c 编译了这段代码编译器(https://www.onlinegdb.com/online_c_compiler),结果相同:打印输出“函数返回真值”。
进一步的实验表明:
将“FALSE”替换为“TRUE”(参见下面的代码片段)、构建、执行它,将产生相同的打印输出(“函数返回真”)。撤消更改并再次构建它并执行它不会更改输出,无论应用程序文件是否在构建之间被删除。
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return TRUE;}
int main() {
if (function_returning_false) {
printf("function returned true\n");
}
}
包含 stdbool
-library 并将定义的“FALSE”和“TRUE”替换为“false”和“true”并没有什么不同(参见下面的代码片段)。
#include <stdio.h>
#include <stdbool.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return false;}
int main() {
if (function_returning_false) {
printf("function returned true\n");
}
}
将“if”语句中的函数“function_returning_false()”替换为布尔值“false”(参见下面的代码片段),构建它,执行它,应用程序将没有打印输出,正如预期的那样。但是,如果更改之后立即撤消并再次构建和执行代码,应用程序将可以正常工作。删除应用程序并重新启动构建它的机器后,描述的现象会重新出现。
#include <stdio.h>
#include <stdbool.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return false;}
int main() {
if (false) {
printf("function returned true\n");
}
}
感谢您的宝贵时间。
您没有正确复制程序。这是重现bug的真实程序:
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int function_returning_false() {return FALSE;}
int main() {
if (function_returning_false) { // note, no ()
printf("function returned true\n");
}
}
所以,它不是调用函数 - 它是将函数作为参数传递给 if
,并且在布尔上下文中,函数将始终是 true
.