我注意到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语言标准吗?为什么?
subarray2
时,n
仅用于地址计算,不会导致存储分配,例如在subarray2++
中,将添加n
个字符的大小。当指针指向的对象与n
的大小不同时,编译器可以在可能的情况下发出警告,但这将是运行时问题,通常不是编译时问题。 - Paul Ogilvie#if 0
更改为#if 1
,您将在该分配上获得警告(将较大的普通数组赋值给较小的普通数组)。如果“指针只是数字”应该没有关系,但对于编译器来说,它似乎有影响。 - Petr Skocik