g++默认不启用C++17标准,必须显式指定-std=c++17或-std=gnu++17才能使用结构化绑定、std::optional等特性,且多文件编译时每个-g++ -c命令都需携带该选项,链接std::filesystem还需额外加-lstdc++fs。

g++ 默认不启用 C++17 标准,直接写 g++ main.cpp -o main 会按较旧标准(如 C++98 或 C++14)编译,遇到 std::optional、std::string_view、内联变量(inline constexpr)等新特性时会报错。
必须显式指定 -std=c++17 才能用 C++17 特性
这是最常被忽略的一步。GCC 不会自动“猜”你想要哪个标准,哪怕代码里用了 std::filesystem 也不会触发升级。
-
-std=c++17是严格遵循 ISO/IEC 14882:2017 标准,禁用 GNU 扩展(如__gnu_linux相关扩展) -
-std=gnu++17启用 C++17 + GNU 扩展(比如__attribute__、typeof),日常开发更常用 - 不要混用
-std=c++17和-std=gnu++14—— 编译器不会合并或降级,而是以最后出现的为准 - 如果用 CMake,需在
CMakeLists.txt中设set(CMAKE_CXX_STANDARD 17),否则g++命令行参数会被覆盖
链接 std::filesystem 需额外加 -lstdc++fs
C++17 引入的 std::filesystem 在 GCC 中不是默认链接的,即使加了 -std=c++17,编译通过但链接会失败,报错类似:
undefined reference to `std::filesystem::__cxx11::status(std::filesystem::__cxx11::path const&)
- 必须在命令末尾加上
-lstdc++fs(注意是小写fs,不是filesystem) - 顺序重要:
-lstdc++fs要放在所有源文件和目标文件之后,否则链接器找不到符号 - 示例完整命令:
g++ -std=gnu++17 main.cpp -o main -lstdc++fs - GCC 11+ 已支持
std::filesystem,但 GCC 8–10 需要该 flag;GCC 7 及更早版本根本不支持
多文件项目中,-std=c++17 要对每个 g++ 命令都加
分步编译时,不能只在链接阶段加标准选项,预处理、编译、汇编每一步都依赖语言标准。
立即学习“C++免费学习笔记(深入)”;
- 错误写法:
g++ -c a.cpp -o a.o(没加-std) →g++ -std=c++17 a.o b.o -o app(只在链接加) - 正确写法:每个
-c命令都要带-std=gnu++17,例如:g++ -std=gnu++17 -c a.cpp -o a.o - 否则,
a.o是按默认标准生成的,可能缺少模板实例化或 ABI 版本不匹配,链接时报undefined reference或运行时崩溃 - Makefile 中建议统一定义:
CXXFLAGS = -std=gnu++17 -Wall -g,然后所有规则复用
最容易被忽略的是:C++17 的某些特性(比如结构化绑定、if constexpr)在语法层面就要求编译器知道标准版本,不加 -std= 就算代码写对了也过不了词法分析——它根本不是“警告后继续”,而是直接报错退出。


















