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

CMake设置C++20失效求助:g++9.4仍采用C++17

C标准切换到C20后__cplusplus仍显示C++17的问题分析

问题背景

为使用std::jthread库,将项目C++标准从17切换到20,在根目录CMakeLists.txt中添加:

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES)

但通过以下代码检测时,输出仍为C++17:

if (__cplusplus == 201703L)
    std::cout << "C++17\n";
else if (__cplusplus == 201402L)
    std::cout << "C++14\n";
else if (__cplusplus == 201103L)
    std::cout << "C++11\n";
else if (__cplusplus == 199711L)
    std::cout << "C++98\n";
else if (__cplusplus == 202002L)
    std::cout << "C++20\n";
else
    std::cout << "pre-standard C++\n";

使用编译器为g++(Ubuntu 9.4.0-1ubuntu1~20.04.1)9.4.0,该版本宣称支持C++20。

核心原因

1. CMake默认启用GNU扩展,传递的是-std=gnu++20而非-std=c++20

g++ 9.x中,当使用带GNU扩展的-std=gnu++20时,__cplusplus宏不会被设置为C20的标准值202002L,而是保持为C17的201703L以兼容旧代码。CMake的CMAKE_CXX_EXTENSIONS默认值为ON,会自动给g++传递-std=gnu++20参数。

2. 标准配置代码的位置错误

如果set(CMAKE_CXX_STANDARD 20)等配置是在add_executable/add_library之后才添加的,这些设置不会作用于已创建的编译目标,编译器仍会沿用之前的C++17标准。

额外注意:g++9.4对std::jthread的支持缺失

std::jthread是C20的新特性,但g直到10.x版本才完全实现该类,g9.4仅支持部分C20特性,即使解决了标准检测问题,也无法正常使用std::jthread。

解决办法

1. 关闭GNU扩展,强制使用纯C++20标准

在CMakeLists.txt中补充配置:

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF) # 关键:禁用GNU扩展,让CMake传递-std=c++20

2. 调整配置代码的位置

确保上述标准配置代码放在add_executable或add_library命令之前,保证配置能覆盖到目标编译参数。

3. 验证编译参数

通过make VERBOSE=1(Makefile生成器)或ninja -v(Ninja生成器)查看实际编译命令,确认参数中包含-std=c++20而非-std=gnu++20。

4. 升级编译器(针对std::jthread需求)

若要使用std::jthread,需将g++升级到10.x或更高版本,比如在Ubuntu 20.04中可通过安装g++-10包实现。

内容的提问来源于stack exchange,提问作者Pedro Lopes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:25:19