VS2022误以C++编译C头文件致指定初始化器报错
问题原因
你猜的没错,确实是VS用C编译器处理了test.h的内容。虽然你把#include "test.h"放在了extern "C"块里,但extern "C"只负责控制链接时的名称修饰规则,不会改变头文件内容的编译语言——因为main.cpp是C源文件,所有被它包含的头文件都会被C编译器解析。而C17及更早的标准不支持结构体的指定初始化器(就是.a = 8这种写法),只有C++20及以上才支持,所以才会报这个错。
解决方案
给你三个可行的解决办法,按需选择:
1. 升级项目的C标准到C20
打开VS2022项目属性:
- 右键项目 -> 属性 -> 配置属性 -> C/C++ -> 语言
- 把“C标准”改成「ISO C20标准(/std:c20)」或者更高版本
这样C编译器就支持指定初始化器语法了,直接编译通过。
2. 修改头文件的初始化写法,兼容C和旧版C++
因为你的结构体只有一个成员,把指定初始化改成普通的位置初始化就行:
typedef struct { int a; } TEST; const TEST MYTEST = {8}; // 去掉.a = ,直接写值
这种写法不管是C编译器还是C++98及以上的编译器都能正常识别,完全兼容。
3. 把MYTEST的定义移到C源文件中
如果不想改初始化写法,也不想升级C++标准,可以把变量定义放到单独的C源文件里,让它用C编译器编译:
- 创建
test.c文件,内容如下:
#include "test.h" const TEST MYTEST = {.a = 8}; // 这里用C编译器编译,支持指定初始化
- 修改
test.h,只保留结构体定义和变量声明:
typedef struct { int a; } TEST; extern const TEST MYTEST; // 只声明,不定义
这样test.c会被VS默认用C编译器编译(识别.c后缀),支持C的指定初始化器;main.cpp包含头文件后,通过extern链接到C编译的MYTEST符号,既保留了你的写法,又不会触发C++编译器的语法错误。
内容的提问来源于stack exchange,提问作者Niclas
相关产品推荐
相关产品推荐

