一个谷歌无法帮我解答的简单问题。在 #ifdef
的上下文中使用 #elif
条件编译指令在 C++ 中是否合法?在 c++11 模式下,所有主要编译器(MSVC 2015/2017,clang,GCC)似乎都可以编译和正常工作,但我不确定它是否符合标准。
一个谷歌无法帮我解答的简单问题。在 #ifdef
的上下文中使用 #elif
条件编译指令在 C++ 中是否合法?在 c++11 模式下,所有主要编译器(MSVC 2015/2017,clang,GCC)似乎都可以编译和正常工作,但我不确定它是否符合标准。
是的,语法允许在先前匹配的#if
、#ifdef
或#ifndef
之后使用#elif
:
if-section:
if-group elif-groupsopt else-groupopt endif-lineif-group:
# if
constant-expression new-line groupopt
# ifdef
identifier new-line groupopt
# ifndef
identifier new-line groupopt
请注意,#ifdef(X)
只是#if defined(X)
的简写,而#ifndef(X)
则是#if ! defined(X)
。
对我而言,在这个问题上最重要的一点实际上是在问题下面 rosshjb 的评论:
@RemyLebeau Yes,我们可以在 #elif 中使用 #ifdef。 但是,如果我们为 #ifdef 情况定义值为 0 的宏,则 #ifdef 情况将其测试为 true。 否则,如果我们为 #elif 情况定义值为 0 的宏,则 #elif 情况将其测试为 false。 - rosshjb Jan 19 '20 at 19:40
因此,如果您有一个类似于以下的代码块:
#ifdef __linux__
<some Linux code here>
#elif _WIN32
<some Windows code here>
#endif
那么第二个测试与第一个测试明显不同 - 第一个测试检查是否定义了__linux__
,而第二个测试检查符号_WIN32
是否为true。在许多情况下它们会表现相同,但不能保证总是如此。
实际上完整的等效语句是:
#ifdef __linux__
<some Linux code here>
#elif defined(_WIN32)
<some Windows code here>
#endif
可能并不是每个人都很明显。
使用Kerrick SB的答案,您也可以将相同的#if
语句编写为:
#if defined(__linux__)
<some Linux code here>
#elif defined(_WIN32)
<some Windows code here>
#endif
这使得defined
在#if
和#elif
中是相同的更加明显。
#if defined (...)
比短形式的#ifdef
更好。 - Violet Giraffe是的,它是被允许的。
语法如下:
if-group elif-groupsopt else-groupopt endif-line
if-group
的定义不仅包括 #if
,还包括 #ifdef
和 #ifndef
,所以 #ifdef ... #elif ... #endif
也可以使用。
#elif
可以与#ifdef
、#ifndef
和#if
同样地配合使用。 - Remy Lebeau#elif
中使用#ifdef
。但是,如果我们将宏定义为值为0
的#ifdef
情况,那么#ifdef
情况会被测试为 true。否则,如果我们将宏定义为值为0
的#elif
情况,那么#elif
情况将测试为 false。 - rosshjb#ifdef
测试宏的存在,而不是其值。而#elif
检测宏的值。 - Remy Lebeau