如何在Visual Studio Community 2019的CMake项目中启用C++17编译?
解决MSVC下CMake配置C++17对齐特性失效问题
你遇到的std::align_val_t未定义的错误,本质是C17标准没有被正确启用——虽然你尝试了设置CXX_STANDARD和/std:c++latest,但CMake 3.8对MSVC的标准传递逻辑有局限性,再加上全局编译选项可能没覆盖到子项目目标,导致编译器还是没开启完整的C17支持。结合VS2019的环境,我给你一套能彻底解决的方案:
问题根源拆解
- CMake版本局限:CMake 3.8对
CXX_STANDARD属性的处理在MSVC上不够完善,全局设置可能不会自动传递给子项目的目标; - 编译选项优先级:你在根目录添加的
/std:c++latest可能被子项目的默认配置覆盖,而且/std:c++latest是包含C++17及后续特性,但有时候不如明确指定/std:c++17稳定; - MSVC严格模式缺失:VS2019的MSVC默认可能启用了一些非标准扩展,导致部分C++17特性无法被正确识别。
完整解决方案
1. 修改根目录CMakeLists.txt
把全局标准配置和MSVC专属设置放在子项目引入之前,确保所有子项目能继承正确的标准:
cmake_minimum_required (VERSION 3.8) project ("lameduck") # 全局强制启用C++17,禁用编译器扩展 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # 针对MSVC启用严格标准模式,避免非标准行为干扰 if(MSVC) add_compile_options(/permissive-) # 如果需要C++20+特性可以保留下面一行,否则优先用明确的C++17 # add_compile_options(/std:c++latest) endif() # 引入子项目 add_subdirectory ("lameduck")
2. 修改子目录(lameduck/CMakeLists.txt)
给目标单独设置标准属性,兜底确保配置不会被覆盖:
# 生成可执行文件 add_executable(lameduck main.cpp) # 针对目标明确设置C++17标准 set_target_properties(lameduck PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF ) # MSVC下手动指定编译选项,确保标准生效 if(MSVC) target_compile_options(lameduck PRIVATE /std:c++17 /permissive-) endif()
为什么这样能解决问题?
- 全局+目标双重设置:既保证所有子项目默认继承C++17,又通过目标属性强制覆盖任何可能的默认配置;
/permissive-选项:让MSVC切换到严格标准模式,严格遵循C++17规范,确保std::align_val_t这类标准特性被正确识别;- 禁用扩展:
CXX_EXTENSIONS OFF让CMake给MSVC生成/std:c++17而不是带扩展的版本,避免编译器启用非标准特性干扰。
这样配置后,重新生成CMake缓存并编译,std::align_val_t的错误应该就会消失,Vec3dAVX的对齐逻辑也能正常工作。
内容的提问来源于stack exchange,提问作者Dev




