c++ 条件包含_c++中条件表达式

c++ 条件包含_c++中条件表达式

编码文章call10242025-02-10 11:19:2715A+A-

纯属搬运, 方便记录

条件包含 - cppreference.com

预处理器支持有条件地编译源文件的某些部分。这一行为由 #if#else#elif#ifdef#ifndef#elifdef#elifndef (C++23 起) 与 #endif 指令所控制。

语法


#if 表达式

#ifdef 标识符

#ifndef 标识符

#elif 表达式

#elifdef 标识符 (C++23 起)

#elifndef 标识符 (C++23 起)

#else

#endif


解释

条件预处理块由 #if#ifdef#ifndef 指令开始,然后可选地包含任意多个 #elif#elifdef#elifndef (C++23 起) 指令,接下来是最多一个可选的 #else 指令,并以 #endif 指令结束。嵌套的条件预处理块会被单独处理。

各个 #if#ifdef#ifndef#elif#elifdef#elifndef (C++23 起) 和 #else 指令所控制的代码块在第一个不属于内部嵌套的条件预处理块的 #elif#elifdef#elifndef (C++23 起)、#else#endif 指令处结束。

#if#ifdef#ifndef 指令测试其所指定的条件(见下文),如果条件求值为真,则编译其控制的代码块。此时后续的 #else#elifdef#elifndef (C++23 起) 和 #elif 指令将被忽略。否则,如果所指定的条件求值为假,则跳过其所控制的代码块,然后处理后续的 #else#elifdef#elifndef (C++23 起) 或 #elif 指令(如果存在)。若后续指令为 #else,则 #else 指令所控制的代码块将会无条件地进行编译。否则,#elif#elifdef#elifndef (C++23 起) 指令按照与 #if 指令相同的方式执行:即测试条件是否满足,并根据其结果决定编译或跳过其所控制的代码块,并在后一种情况下继续处理后续的 #elif#elifdef#elifndef (C++23 起) 和 #else 指令。条件预处理块以 #endif 指令结束。

条件的求值

#if, #elif

表达式 是常量表达式。

表达式可含有形如“defined 标识符”或“defined (标识符)”的一元运算符。当此 标识符 已经被定义为宏名,或者此 标识符__has_include (C++17 起)时结果为 1,否则结果为 0。

在进行所有宏展开和 defined__has_include (C++17 起) 表达式的求值后,任何非布尔字面量的标识符都被替换成数字 0(这包含词法上为关键字的标识符,但不包括如 and 之类的代用记号)。

表达式 求值为非零值时,包含其所控制的代码块,否则跳过该代码块。

预处理器语境中, __has_cpp_attribute 表达式检测给定属性记号是否受支持及其受支持版本。见属性测试。

(C++20 起)



注: CWG 1955 前,“#if cond1 ... #elif cond2”和“#if cond1 ... #else”后面跟着“#if cond2”是不同的,因为当 cond1 为真时第二个 #if 将被跳过,且 cond2 并不需要是良构的,而 #elif 中的 cond2 则必须是合法的表达式。 CWG 1955 开始,引领跳过的代码块的 #elif 也被跳过。

组合指令

检查标识符是否被定义为宏名。

#ifdef 标识符#if defined 标识符 实质上等价。

#ifndef 标识符#if !defined 标识符 实质上等价。

#elifdef 标识符 #elif defined 标识符 实质上等价

#elifndef 标识符 #elif !defined 标识符 实质上等价

(C++23 起)



注解

#elifdef#elifndef 指令于 C++23 标准化,不过鼓励实现将它们作为遵从的扩展向后移植到旧语言模式。

示例

#define ABCD 2
#include 
 
int main()
{
 
#ifdef ABCD
    std::cout << "1: yes\n";
#else
    std::cout << "1: no\n";
#endif
 
#ifndef ABCD
    std::cout << "2: no1\n";
#elif ABCD == 2
    std::cout << "2: yes\n";
#else
    std::cout << "2: no2\n";
#endif
 
#if !defined(DCBA) && (ABCD < 2*4-3)
    std::cout << "3: yes\n";
#endif
 
 
// 注意若编译器不支持 C++23 的 #elifdef/#elifndef 指令则会选择“不期待”块(见后述)。
#ifdef CPU
    std::cout << "4: no1\n";
#elifdef GPU
    std::cout << "4: no2\n";
#elifndef RAM
    std::cout << "4: yes\n"; // 期待的块
#else
    std::cout << "4: no!\n"; // 由于跳过未知的指令不期待地选择此块
                             // 并直接从 "#ifdef CPU" “跳”到此 "#else" 块
#endif
 
// 为修复此问题,我们可以条件性地仅若支持 C++23 指令 #elifdef/#elifndef
// 才定义 ELIFDEF_SUPPORTED 宏。
#if 0
#elifndef UNDEFINED_MACRO
#define ELIFDEF_SUPPORTED
#else
#endif
 
#ifdef ELIFDEF_SUPPORTED
    #ifdef CPU
        std::cout << "4: no1\n";
    #elifdef GPU
        std::cout << "4: no2\n";
    #elifndef RAM
        std::cout << "4: yes\n"; // 期待的块
    #else
        std::cout << "4: no3\n";
    #endif
#else // 不支持 #elifdef 时使用累赘的旧 `#elif defined`
    #ifdef CPU
        std::cout << "4: no1\n";
    #elif defined GPU
        std::cout << "4: no2\n";
    #elif !defined RAM
        std::cout << "4: yes\n"; // 期待的块
    #else
        std::cout << "4: no3\n";
    #endif
#endif
}

可能的输出:

1: yes
2: yes
3: yes
4: no!
4: yes
点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4