我对 C99 的可变修改类型系统产生了浓厚的兴趣。这个问题是受这个启发的。
检查这个问题的代码,我发现了一些有趣的东西。考虑这段代码:
int myFunc(int, int, int, int[][100]);
int myFunc(int a, int b, int c, int d[][200]) {
/* Some code here... */
}
这显然不会(也不会)编译。但是,这段代码:
int myFunc(int, int, int, int[][100]);
int myFunc(int a, int b, int c, int d[][c]) {
/* Some code here... */
}
编译时甚至没有警告(在 gcc 上)。
这似乎意味着可变修改的数组类型与任何非可变修改的数组类型兼容!
但这还不是全部。您会期望变量修改的类型至少会打扰使用哪个变量来设置其大小。但它似乎没有这样做!
int myFunc(int, int b, int, int[][b]);
int myFunc(int a, int b, int c, int d[][c]) {
return 0;
}
也编译没有任何错误。
所以,我的问题是:这是正确的标准化行为吗?
此外,如果可变修改的数组类型真的与任何具有相同维度的数组兼容,这是否意味着令人讨厌的安全问题?例如,考虑以下代码:
int myFunc(int a, int b, int c, int d[][c]) {
printf("%d\n", sizeof(*d) / sizeof((*d)[0]));
return 0;
}
int main(){
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
myFunc(0, 0, 100, &arr);
return 0;
}
编译并输出 100,没有错误或警告,什么都没有。在我看来,这意味着即使您通过 严格检查数组的大小,也可以轻松进行越界数组写入sizeof
,而不是进行一次强制转换,甚至打开所有警告!还是我错过了什么?