我注意到C编译器(gcc,clang,tinycc)允许我在没有警告的情况下将指向更大数组的指针分配给指向较小VLA的指针:
#include <stdio.h>
#if !__TINYC__
void take_vla(int N, char const X[1][N]) { printf("%zd\n", sizeof(*X)); }
#endif
int main()
{
static char bigarray[]="0123456789abcdefghijklmnopqrstuvwxyz";
//VLA
int n = 3;
char const (*subarray2)[n]=&bigarray;
//char const (*subarray3)[(int){3}]=&bigarray; //VLA but clang doesn't see it as such (a bug, I guess)
#if !__TINYC__
take_vla(3,&bigarray);
take_vla(3,&"abcdefg");
#endif
#if 0
char const (*subarray1)[3]=&bigarray; //-Wincompatible-pointer-types
#endif
}
这是符合标准的C吗?
答案 0 :(得分:3)
const char[3]
与char[37]
不兼容。
Nor是“指向合格类型的指针”与“指向类型的指针”兼容-请勿将其与“指向类型的合格指针”混合使用。 (不幸的是,常量正确性不适用于数组指针。)
相关部分是简单分配C17 6.5.16.1的规则:
- 左操作数具有原子,合格或不合格的指针类型,并且(考虑到 左值转换后左操作数将具有的类型)两个操作数均为 指向兼容类型的合格或不合格版本的指针,以及指向的类型 到左边的所有限定词都指向右边;
查看各种编译器:
gcc对于检查C一致性没有用。您必须使用-std=cxx -pedantic-errors
进行编译。之后,gcc会正常运行:gcc -std=c17 -pedantic-errors
:
错误:具有不同限定符的数组的指针在ISO C [-Wpedantic]中不兼容
icc与gcc提供相同的诊断,效果很好。
而clang -std=c17 -pedantic-errors
不报告错误,因此显然不符合C标准。