我使用Visual Studio 9.0(2008)编译了一些代码。
行为符合预期,但是当我分配一些带有一些手工函数的2D数组时,Visual Studio会生成一些C4133警告:
void ** alloc_2d(int w, int h, size_t type_size);
void free_d2(void ** mem);
int main (void)
{
float ** data;
/* Here is generated a C4133 warning:
"incompatible type from void ** to float **" */
data = alloc_2d(100, 100, sizeof **data);
/* do things with data */
/* free data */
free_2d(data);
return 0;
}
我知道为什么会生成此警告,但是我想知道应该怎么做才能使其安静。
我该怎么办?
alloc_2d
调用周围的警告(带有一些特定于Visual Studio的宏)?第二个问题:
void**
隐藏的背后是两个数组:一个大数组用于存储我需要连续的所有数据,另一个大数组用于浏览不同行。
实现看起来像(我删除了错误检查)
void **alloc_2D_array(int w, int h, size_t size)
{
void ** mem = malloc(w * sizeof *mem);
*mem = malloc(w*h*size);
for (i = 1; i < w; ++i)
{
mem[i] = (void*)((char*)mem[0] + i*w*size);
}
return mem;
}
C中的通用指针类型为void*
。但这并不意味着,void**
也是一个通用的指针类型,该规则不会递归应用。
相反,从一个转换void**
到float**
或周围的其他方法是一个无效的指针转换。它们不是兼容类型-编译器必须发出诊断消息。忽略警告可能会导致数据未对齐或严格的别名问题(无论哪种情况都存在错误)。
我该怎么办?
修复代码,使其不包含禁止的指针转换。
较新/其他的编译器是否意识到这种转换?
自C的首次标准化以来,此特定规则未曾更改。
至于应该如何修改代码……不应该。您应该从头开始重写它,以便它分配数组而不是“基于指针的查找表”。没有明显的理由使您从此处的这种查找表中受益,但是有许多原因使您避免使用它。
此外,如果您使用指向VLA的指针,您的代码将更具可读性。
有关如何正确执行此操作的示例,请参见正确分配多维数组(代码示例位于答案的最底部)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句