涉及文字的比较安全吗?

Comparisons involving literals safe?

考虑代码:

#define LITERAL 1.0

int main()
{
    double x = LITERAL;

    if (x == LITERAL) return 1;
    else return 0;
}

这是否保证 return 1 对于我们设置的任何数字双精度值 LITERAL(不仅是 1.0,还有任何其他双精度文字)?

编辑:为什么问题因为 "missing details" 而关闭?这是一个定义明确的 C/C++ 问题,并得到了很好的答案。不需要更多细节,这是关于这些语言如何工作的一般性问题。

首先,您必须假设一个(试图)符合附件 F 的实现,否则所有的赌注都会被取消;没有附件 F(IEEE 浮点)C 允许所有浮点结果任意伪造。

然后,根据语言规范,根据您的 C 实现对 FLT_EVAL_METHOD 的定义,是或否。

如果值为 0 或 1,则为。文字被解释为 doubledouble 对象忠实地存储该值,相等运算符产生 1(真),反映了这一点。

如果值为 2,则仅当字面量是可表示的 double 的精确十进制表示形式或以足够的精度表示它与仅超过 long double 精度的字面量不同时.否则(例如,如果它类似于 0.1),因为在 long double 中用 excess precision 解释文字,将 initialization/assignment 格式化为 double 对象将精度截断为标称 double 精度。然后保证相等比较结果为 0(假)。你可以see this in action on Compiler Explorer(注意:去掉volatile你可以看到它优化为return一个常量0)。

为了让事情变得更复杂,GCC 默认情况下 是错误的 ,除非你使用 -std=c..-fexcess-precision=standard,而 总是这样在 C++ 模式下它是错误的,并且 clang/LLVM 总是错误的。因此,在精度过高的目标上(32 位 x86 或 m68k,唯一具有 FLT_EVAL_METHOD 而不是 0 或 1 的与现实世界相关的目标)会发生可怕的事情。要了解它们变得有多糟糕,请参阅 GCC issue 93806 和(递归地)所有 "See Also" 相关问题。

所以出于实际目的,是的,除了 32 位 x86 和 m68k 之外的所有东西,并且在正确的 C 实现中没有(但也许是,因为你的编译器可能坏了)。