为什么使用 C 的断言函数会跳过对其前面的条件的求值?

hum*_*ean 2 c

我使用 C 的assert.h assert函数的方法与此类似:

\n
int x = 3;\n\nif (x == 3)\n    printf("x is 3 \xe2\x9c\x85");\n\nassert(x != 3);\n
Run Code Online (Sandbox Code Playgroud)\n

当运行它时,我发现该if语句被完全跳过,并且程序在到达该assert语句时终止。不用说,在我找到罪魁祸首之前,这在我的程序中造成了一些极其讨厌的错误。这可能是什么原因造成的?为什么条件被完全跳过?如果没有被跳过,那么为什么里面的代码没有被执行呢?我在这里设置了一个在线示例。

\n

Dar*_*tom 6

if语句不会被跳过。

\n

assert执行时,不被视为“干净”的程序终止。因此,I/O 缓冲区不会被刷新。尝试添加fflush()对显式刷新stdout缓冲区的调用:

\n
int x = 3;\n\nif (x == 3)\n{\n    printf("x is 3 \xe2\x9c\x85");\n    fflush(stdout);\n}\n\nassert(x != 3);\n
Run Code Online (Sandbox Code Playgroud)\n

以下是 C17 标准的相关段落(斜体部分是我的):

\n
\n

7.2.1.1

\n

断言宏将诊断测试放入程序中;它扩展为 void 表达式。执行时,如果表达式(应具有标量类型)为 false(即比较等于 0),则断言宏会写入有关失败的特定调用的信息(包括参数的文本、参数的名称)源文件、源行号和封闭函数的名称 \xe2\x80\x94 后者分别是标准错误流上采用实现定义格式的预处理宏__FILE____LINE__标识符) 的值。然后它调用中止函数。__func__

\n
\n
\n

7.22.4.1

\n

abort 函数会导致程序异常终止,除非信号 SIGABRT 被捕获并且信号处理程序不返回。是否刷新具有未写入缓冲数据的打开流、关闭打开流或删除临时文件是实现定义的。

\n
\n