You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求问:C++98起合法的构造在C++20与C++23中是否有行为差异?

C版本检测程序:添加C23检测逻辑的方案

你写的这款靠C标准语法/行为差异检测版本的程序思路很有意思,目前的实现已经覆盖了C98到C20的区分逻辑。关于C23的检测,符合「自C98起合法但行为改变」的构造确实比较少见——毕竟C23的更新大多是新增特性,而非修改旧特性的既定行为。

不过还是有一个可以尝试的方向:

std::string::operator[]的行为变化

在C11到C20的标准里,std::string的operator[]允许传入等于字符串size()的索引,此时会返回指向末尾终止空字符的引用;但C++23修正了这一规则,明确要求索引必须严格小于size(),否则属于未定义行为。

需要注意的是,C98标准中operator[]使用等于size()的索引本身属于未定义行为,但很多主流编译器在C98模式下的处理逻辑和C11-20一致。如果你的目标编译器符合这个情况,可以用以下逻辑区分C23:

// ... 现有代码 ...
} else {
    std::string s = "test";
    bool is_cpp23 = false;
    try {
        char c = s[s.size()];
        // C++11-20中此处会返回'\0',C++23中行为未定义,多数编译器会返回非'\0'值或崩溃
        is_cpp23 = (c != '\0');
    } catch (...) {
        is_cpp23 = true;
    }
    if (is_cpp23) {
        std::cout << "C++23" << std::endl;
    } else {
        std::cout << "C++20" << std::endl;
    }
}

备选方案:__cplusplus宏

如果严格要求「自C98起合法」,目前最可靠的方式还是直接检查__cplusplus宏的值——C23对应的宏值是202302L,这虽然和你依托语法特性的初衷不符,但胜在稳定可靠:

// ... 现有代码 ...
} else {
#if __cplusplus >= 202302L
    std::cout << "C++23" << std::endl;
#else
    std::cout << "C++20" << std::endl;
#endif
}

内容的提问来源于stack exchange,提问作者Purple P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 15:07:27