错误:`#elif没有表达式` - 仅在Windows上发生

时间:2014-04-30 13:32:36

标签: c++ gcc g++ mingw

我正在尝试使用我在Windows上创建的库来编译项目,使用MinGW 4.8.1 x86。该项目在Linux上编译良好。

Common.hpp 包含在其他所有内容之前,并根据当前操作系统定义一些宏。然后包含 ConsoleFmt.hpp ,它包含一个文件,具体取决于先前定义的宏。

但是我收到了错误 - 这是代码和错误消息:


Common.hpp

#if (__linux || __unix || __posix)
    #define SSVU_OS_LINUX
#elif (_WIN64 || _WIN32)
    #define SSVU_OS_WINDOWS
#else
    #define SSVU_OS_UNKNOWN
#endif

ConsoleFmt.hpp

#include "Common.hpp"

#ifdef SSVU_OS_LINUX
    #include "SSVUtils/Core/ConsoleFmt/Internal/ConsoleFmtImplUnix.hpp"
#elif SSVU_OS_WINDOWS
    #include "SSVUtils/Core/ConsoleFmt/Internal/ConsoleFmtImplWin.hpp"
#else
    #include "SSVUtils/Core/ConsoleFmt/Internal/ConsoleFmtImplNull.hpp"
#endif

错误:

  

错误:#elif没有表达式:

     

#elif SSVU_OS_WINDOWS

我的代码无效或MinGW中是否有错误?我想我正在使用#elif

3 个答案:

答案 0 :(得分:11)

#elif#else#if的缩写,而非#else#ifdef,因此您的行应为:

#elif defined(SSVU_OS_WINDOWS)

修改:由于未定义的宏在0表达式中扩展为#if,因此您还可以使用原始变体并定义值为1的活动宏。 (正如hvd刚发布并解释的那样。)

答案 1 :(得分:4)

安全解决方案IMO将以这样的方式定义SSVU_OS_*:无论您使用#if还是#ifdef都无关紧要。

#if (__linux || __unix || __posix)
    #define SSVU_OS_LINUX 1
#elif (_WIN64 || _WIN32)
    #define SSVU_OS_WINDOWS 1
#else
    #define SSVU_OS_UNKNOWN 1
#endif

这使您的#ifdef / #elif可以正常工作。为了保持一致性,您可以将其清理到

#if SSVU_OS_LINUX
    #include "SSVUtils/Core/ConsoleFmt/Internal/ConsoleFmtImplUnix.hpp"
#elif SSVU_OS_WINDOWS
    #include "SSVUtils/Core/ConsoleFmt/Internal/ConsoleFmtImplWin.hpp"
#else
    #include "SSVUtils/Core/ConsoleFmt/Internal/ConsoleFmtImplNull.hpp"
#endif

但并非绝对必要。

确保您的宏工作而不需要#ifdef / defined检查允许更简单的表达式,如果您组合多个检查(就像您已经使用其他人的宏一样:您使用{{1}检查多个})。

答案 2 :(得分:4)

解释为什么它在Linux中运行但在Windows中失败:

#elif (_WIN64 || _WIN32)

如果已定义_WIN64,则会被替换,例如如果已定义

#define _WIN64
#define _WIN32

然后第一行扩展到

#elif ( || )

会产生错误。但是,如果这些令牌根本没有定义,则会被0替换为

#elif (0 || 0)

没关系。