为何无法将字符串数组(初始化列表)强制转换为自身类型const char*[]?
const char*[]? 核心问题拆解
你遇到的问题本质和类型匹配无关,是C语言的数组初始化规则与复合字面量属性共同作用的结果:
复合字面量不属于编译期常量表达式
你写的(const char*[]){"t1", "t2", "t3", "t4"}是C99的复合字面量语法,用来创建临时数组对象。但这个对象的存储期是自动的(类似局部变量)——哪怕内部元素是静态存储期的字符串字面量,整个复合字面量表达式本身不是编译期常量,这就是编译器报错“non-constant array expression”的原因。数组不能用数组类型表达式初始化
C语言中数组是不可拷贝的,你不能用数组类型的右值(比如复合字面量创建的临时数组)初始化另一个数组。哪怕两者类型完全一致,这种写法也不被允许——数组初始化只接受初始化列表({...})或字符串字面量(针对字符数组),不接受数组类型的表达式。
正确写法
直接初始化数组(推荐)
去掉多余的强制转换,直接用初始化列表填充数组:
const char* foo[] = {"t1", "t2", "t3", "t4"}; // 完全合法
这里的{"t1", ...}是初始化列表,而非数组表达式,编译器会直接将字符串字面量的地址填充到foo数组的各个元素中。
用指针接收复合字面量(适配特定场景)
如果确实需要用复合字面量形式(比如函数传参),可以用指针接收:
const char** foo = (const char*[]){"t1", "t2", "t3", "t4"}; // 合法
这是因为数组类型表达式在多数语境下会自动退化为指向首元素的指针,复合字面量创建的临时数组会被转换为const char**类型指针,赋值给foo。
类型补充说明
{"t1", "t2", "t3", "t4"}本身不是const char*[]类型,它是初始化列表,仅在直接初始化数组的语境下,才会被编译器解析为对应数组的元素初始值。而复合字面量(const char*[]){...}确实创建了const char*[4]类型的数组,但如前所述,这个数组不能用来初始化另一个数组。
内容的提问来源于stack exchange,提问作者Qwert Yuiop

