预处理器替换中乘以分数的问题(#define)

Issue with multiplication by a fraction in pre-processor Substitution (#define)

我想从代码开始

#define myConst (419*0.9)
#define myConst1 (419*.9)
#define myConst9 (myConst1*.9)
#define myConst11 (419*1.1)

int main()
{
    printf("myConst:%d\n",myConst);
    printf("myConst1:%d\n",myConst1);
    printf("myConst9:%d\n",myConst9);
    printf("myConst11:%d\n",myConst11);
    return 0;
}

这给了我

的输出

myConst:1913895624
myConst1:1
myConst9:1
myConst11:1

我不知道为什么在#define 中乘以分数会导致与预期不同的值?而且 myConst 的值也在不断变化,例如,我观察到的一些值是 -254802840 -1713343480 466029496.而且 myConst1myConst9myConst11 也给了我 1,这对我来说是不合逻辑的.

欢迎就此进行任何解释。

#define在此没有任何作用;问题是当 printf 期望 int 时你传递了 double (由于 %d 说明符);从技术上讲,这是未定义的行为,因此允许发生任何事情。

现在,如果这是在 32 位 x86 上构建的,您可能会 int 重新解释浮点数的低 32 位,因为所有参数通常都在堆栈上传递。但我猜这是 64 位 x86 上的 运行,如果参数是浮点数,则在不同的寄存器中传递。在这种情况下,printf 只是读取此时某个寄存器中恰好存在的任何垃圾,这些值中没有太多逻辑。

请注意,几乎所有编译器都会警告您格式字符串与实际传递的值之间的这种不匹配。对于 gcc 和 clang,我建议您启用此警告(-Wformat,包含在 -Wall 中,您应该 明确地 启用),并可能将其标记为实际错误 (-Werror=format),因为没有合法理由像这样破坏 printf