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.