我正在尝试使用我在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
。
答案 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)
没关系。