C2X中auto类型推断的限制及数组初始化失败问题咨询
关于C语言中auto关键字的类型推断问题
测试代码
int main() { auto status = 203; auto static const str = "Hello"; auto static const strs = {"Hello", "World"}; return status; }
编译错误信息
auto.c: In function ‘main’: auto.c:5:30: error: expected expression before ‘{’ token 5 | auto static const strs = {"Hello", "World"}; | ^ compilation terminated due to -Wfatal-errors.
问题解答
1. 为何无法推断strs的类型?
在C语言中,auto的类型推断规则要求初始化器必须是单一表达式,而{"Hello", "World"}属于聚合初始化列表,并非一个完整的表达式。编译器无法仅通过这个列表确定你要声明的是数组、结构体还是其他聚合类型,因此无法完成类型推断,导致编译错误。
如果要让strs被正确推断类型,需要显式将初始化列表转换为数组类型,比如:
auto static const strs = (const char*[]){"Hello", "World"};
2. auto的其他限制(除不能作为函数返回类型/参数外)
- 必须伴随初始化器:
auto声明的变量不能只写auto x;,编译器需要通过初始化值推导类型,未初始化的auto变量会触发编译错误。 - 不能用于数组大小的声明:比如
auto int arr[auto];是非法的,数组大小必须是编译期可确定的常量,auto无法用于推导该值。 - 不能用于类型别名(typedef)定义:
typedef auto MyType;这类写法不符合C标准,会报错。 - 无法直接推断匿名聚合类型:比如
auto x = (struct {int a; char b;}){1, 'c'};这种写法在部分编译器中可能被支持,但不属于C标准规定的合法用法,移植性差。 - 静态存储期的
auto变量初始化器必须是常量表达式:比如auto static var = rand();会报错,因为rand()是运行期函数,不是编译期常量。
内容的提问来源于stack exchange,提问作者Madagascar
相关产品推荐
相关产品推荐

