C语言复合类型疑问:C11 6.2.7 p3条款相关问题咨询
C11 6.2.7 p3数组复合类型问题解答
C11 6.2.7 p3:
若两种类型均为数组类型,则适用以下规则:
- 若其中一种类型是已知常量大小的数组,则复合类型为该大小的数组。
- 否则,若其中一种类型是由未求值表达式指定大小的变长数组,行为未定义。
- 否则,若其中一种类型是指定了大小的变长数组,则复合类型为该大小的变长数组。
- 否则,若其中一种类型是大小未指定的变长数组,则复合类型为大小未指定的变长数组。
- 否则,两种类型均为大小未知的数组,复合类型为大小未知的数组。
问题1:未求值表达式指定大小的变长数组复合类型场景示例
未求值表达式指的是在当前语境下不会被实际计算值的表达式,比如非变长数组作为操作数时的sizeof表达式、_Alignof表达式等。以下是符合规则的场景:
int n = 10; // 第一个声明:参数是指向以未求值表达式指定大小的变长数组的指针 void test(int (*)[sizeof(n)]); // 第二个声明:参数是指向以普通变量指定大小的变长数组的指针 void test(int (*)[n]); int main() { test(NULL); // 此处触发未定义行为 return 0; }
这里sizeof(n)是未求值表达式——编译器仅获取n的类型大小,不会实际读取n的数值。当尝试复合这两个test的声明类型时,满足条款中“其中一种类型是由未求值表达式指定大小的变长数组”的条件,因此程序行为未定义,可能出现编译报错、运行异常等不可预测的结果。
问题2:两种指定大小的变长数组的复合类型
针对给出的代码:
int n=2; int m=3; void f(char(*)[n]); void f(char(*)[m]);
根据C11 6.2.7 p3的规则优先级,当两个类型都是指定了大小的变长数组时,前四条规则均不适用:既没有常量大小数组,也没有未求值表达式指定的变长数组,也不存在“仅一种是指定大小变长数组”的情况,也不属于未指定大小的变长数组。这种场景下,C标准并未明确规定复合类型的具体形式,因此程序行为属于未定义。
部分编译器可能会自行采用第一个或第二个声明的数组大小作为复合类型的大小,但这属于编译器扩展行为,并非C标准的强制要求,依赖这种行为会导致程序的可移植性极差。
内容的提问来源于stack exchange,提问作者user24723440
相关产品推荐
相关产品推荐

