我有几个理由为固定长度的数组定义一个类型,如下所示:
typedef float fixed_array_t[NX][NY];
然后我想将对fixed_array_t
实例的引用传递给其他函数。虽然我看到正确的行为,但我从GCC和CLANG得到编译器警告。
这个编译器警告告诉我什么,我的代码应该如何修改以避免警告?额外的好处是,为什么我要#define
数组的大小?编译时常量显然不起作用。error: variably modified ‘fixed_array_t’ at file scope
下面是一个小的演示代码:
#include <stdio.h>
#define NX 2 // also, why does const int NX = 2; not work?
#define NY 3
typedef float fixed_array_t[NX][NY];
void array_printer( const fixed_array_t arr )
{
int i, j;
for (i = 0; i < NX; i++ )
for( j=0; j < NY; j++ )
printf("Element [%d,%d]=%fn", i,j, arr[i][j] );
}
int main( int argc, char ** argv )
{
fixed_array_t testArray = { {1,2,3}, {4,5,6} };
array_printer( testArray );
}
GCC警告:
warning: passing argument 1 of ‘array_printer’ from incompatible pointer type
CLANG警告(实际在OpenCL中编译等效代码):
warning: incompatible pointer types passing 'fixed_array_t' (aka 'real [2][3]'), expected 'real const (*)[3]'
程序运行正常:
Element [0,0]=1.000000
Element [0,1]=2.000000
Element [0,2]=3.000000
Element [1,0]=4.000000
Element [1,1]=5.000000
Element [1,2]=6.000000
我认为这是一个问题的原因是array_printer
可以传递它认为是const char
(通过指针引用),但调用代码有一个非const引用,因此可以改变指向的值。
尝试改变:
void array_printer( const fixed_array_t arr )
void array_printer( fixed_array_t arr )
这只是c语言中一个不幸的角落。
形式参数const fixed_array_t arr
的类型是const float (*arr)[XY]
的同义词,实际参数totalArray
的计算结果为float (*)[XY]
类型。
A pointer to array XY of float
不被认为隐式地转换为 pointer to array XY of const float
。
如果你只是想解决这个问题,你可以使用struct
来封装你的数组:
$ cat struct.c ; make CFLAGS=-Wall -Wextra struct ; ./struct
#include <stdio.h>
#define NX 2
#define NY 3
typedef struct fixed {
float arr[NX][NY];
} fixed_t;
void array_printer( const fixed_t f)
{
int i, j;
for (i = 0; i < NX; i++ )
for( j=0; j < NY; j++ )
printf("Element [%d,%d]=%fn", i,j, f.arr[i][j] );
}
int main(int argc, char *argv[]) {
fixed_t f = {.arr={ {1,2,3}, {4,5,6} }};
array_printer(f);
return 0;
}
cc -Wall struct.c -o struct
Element [0,0]=1.000000
Element [0,1]=2.000000
Element [0,2]=3.000000
Element [1,0]=4.000000
Element [1,1]=5.000000
Element [1,2]=6.000000
没有警告,没有错误,只是稍微让人讨厌一点(例如,array_printer
中的f.arr[][]
而不是arr[][]
)。
如果你修改struct fixed
以包含NX
和NY
维度,你甚至可以在你的程序中有多个不同大小的对象。(虽然您会稍微失去编译时间已知边界的好处,但我不确定这到底给您带来了多少好处。)