我正在 Visual Studio Community 中使用 C++20 编写跨平台代码,但我陷入了以下代码的输出:
#define WINDOWS (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
#define UNIX (defined(__unix__) || defined(__unix))
constexpr bool is_unix1()
{
#ifdef UNIX
return true;
#else
return false;
#endif
}
constexpr bool is_unix2()
{
#ifdef defined(UNIX)
return true;
#else
return false;
#endif
}
int main()
{
cout << std::boolalpha << is_unix1() << " " << is_unix2() << endl;
}
当我在 Windows 中从 VS Community 内部运行此代码时,我得到以下输出:
true false
有人可以解释为什么
is_unix1()
被评估为false
而is_unix2()
被评估为true
吗?
我开始知道
defined(...)
是编译器特定的,它不是标准 C++ 的一部分。但直接使用宏会导致奇怪的行为,我不知道在这里使用哪种方法。
defined
不是特定于编译器的。它在 C++ 标准中指定。
#ifdef defined(UNIX)
根本就是无效的语法,编译器必须对此进行诊断。 #ifdef
后面必须跟一个标识符,然后是换行符。它根据标识符是否定义为宏来有条件地编译代码。
因此 #ifdef UNIX
始终编译 then 分支,因为您事先将 UNIX
定义为宏。
你想要的似乎是这样的
#if (defined(__unix__) || defined(__unix))
#if
根据给定表达式进行条件编译,该表达式可以包含 defined
运算符,根据标识符是否定义为宏,分别计算为 0
或 1
。
但是,您无法将
(defined(__unix__) || defined(__unix))
隐藏在 UNIX
宏后面,然后让它在控制 #if
表达式中展开。如果这样的扩展产生 defined
标记,则程序的行为是未定义的。
所以你真正想要的是
#if (defined(__unix__) || defined(__unix))
#define UNIX
#endif
然后后来
#if UNIX