MinGW 中预处理器 g++ 的奇怪行为

Strange behavior of the preprocessor g++ in MinGW

我有代码:

   #if _MSC_VER <= 1300 


     float round(float f)
    {
        if (f < 0)
            return ceilf  (f - 0.5);
        else
            return floorf (f + 0.5);
    }
    #endif

上面的行只能在旧版本的 Visual C++ 编译器中编译。 我用 MinGW 编译器编译这段代码。那里没有像 _MSC_VER 这样的符号,它的代码不需要编译,因为表达式 #if _MSC_VER <= 1300 必须等于 false。但是,它编译。 有人可以解释一下为什么会这样吗?

在 MinGW 中编译为 GNU 6.3.0。

如果未定义 _MSC_VER,则 编译器 将看不到从 #if#endif 的任何代码(包括 #if) .

根据上下文,编译器将看到有效的源代码,并成功编译它。请放心,您的 round 版本不会构成编译程序的一部分,尽管 std::round 可能已隐式包含在某处。

最后,使用加法常量 0.5 来设计 round 函数存在错误。参见 Why do lots of (old) programs use floor(0.5 + input) instead of round(input)?

好吧,在 g++ 上 _MSC_VER 未定义,正如您所指出的,它是特定于 Visual C++ 的。

您可以尝试添加以下内容:

#ifdef _MSC_VER
#if _MSC_VER <= 1300

// Your code

#endif
#endif

此外,如果我正在正确阅读 C++ 标准,未定义的标识符将替换为 0,因此它会通过你的条件并编译,就好像你正在使用它一样 "ancient Visual C++"。

摘自16.1 条件包含:

After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers and keywords, except for true and false, are replaced with the pp-number 0, and then each preprocessing token is converted into a token.