添加“!!”的意图c语言函数调用前

the intention of adding "!!" before a function call in c language

我查看了 coreutils 的源代码树,然后我发现下面的代码让我有些困惑。 (在 coreutils-8.23/lib/getopt.c 第 237 行)

d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT");

'!' 的使用正在反转其操作数的逻辑状态,如果 A 为真,则 !A 为假,因此 !!A 再次为真。不明白作者的用意

这通常是为了强制 return 变成 10

如果 return 是 0NULL,那么 !!<expression> 的最终状态将是 0,因此 false .

如果 return 不是 0NULL,那么最终状态将是 1,因此 true

Further reference here.

当使用非 bool 作为位掩码时,您有时会看到这一点。

任何非零值都是真实的。否定非零值会产生 0,这是假的。再次否定它,总是产生 1,这是真实的。请注意,此最终结果可能与输入(可以是任何其他真值)不同。

基本上它将值从 (true: 1-255, false: 0) 映射到 (true: 1, false: 0)

正如其他人所指出的,目的是保证真实值为 1 而不是所有可能的非零值。

这可以防止人们依赖 true 为 1 的错误,从而导致以下错误:

env = getenv("POSIXLY_CORRECT")
if (env == true) {
    // handle the true case
}

工程师会用!!作为对坏编码器的防御。是的,最好不要编写有错误的代码,但确保错误永远不会咬你几乎同样好。

请注意,将布尔值与 true 进行比较仍然是错误编码 (tm),即使您使用的是 !!诡计。没有理由进行超过 if (bool_var) 的任何测试。并且给出的示例也是次优的,因为它依赖于 NULL 为 0,这可能并非在所有体系结构上都是如此。你给的代码真的应该是

d->__posixly_correct = posixly_correct || getenv("POSIXLY_CORRECT") != NULL;

防止 0 是合法内存地址并且恰好是存储 getenv() 的 return 的位置的情况