我在Linux中有奇怪的警告。在Windows上的Visual Studio中,代码编译和工作良好,但我需要用GCC c90编译它,我得到这些警告:
我已经像这样初始化了矩阵:
typedef float mat[4][4];
现在我想创建一个矩阵数组:
mat MAT_A = { 0 };
mat MAT_B = { 0 };
mat MAT_C = { 0 };
mat *matrices[3] = {MAT_A, MAT_B, MAT_C};
我已经声明了函数:
void get_input(mat** matrices);
并使用:
get_input(&matrices);
代码工作良好,但我需要编译它与gcc c90。我得到这样的警告:
warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
mat *(*matrices)[3] = {MAT_A, MAT_B, MAT_C};
^~~~~
和
warning: passing argument 1 of ‘get_input’ from incompatible pointer type [-Wincompatible-pointer-types]
flag = get_input(&matrices);
^
mat *matrices[3]
是指向mat
的3个指针数组。所以需要用指向mat的指针来初始化它
mat *matrices[3] = {&MAT_A, &MAT_B, &MAT_C};
而且,当调用get_input(&matrices);
时,&matrices
是指向一个包含3个指向mat
的指针的数组的指针。这不是get_input()
所期望的,它是指向mat
的指针的指针。只使用:
get_input(matrices);
表达式matrices
被转换为指向其第一个元素的指针,该元素是指向mat
的指针。因此,表达式的类型是指向mat
的指针,这正是get_input
所期望的。
现在代码编译没有警告。见https://godbolt.org/z/84qd4rrnx
由于这个类型定义声明
typedef float mat[4][4];
数组声明为
mat MAT_A = { 0 };
隐式转换为声明中的第一个元素
mat *matrices[3] = {MAT_A, MAT_B, MAT_C};
的类型为float( * )[4]
。但是变量矩阵被声明为具有元素类型float ( * )[4][4]
。这些类型不兼容。
实际上你有以下声明
float ( *matrices[3] )[4][4] = {MAT_A, MAT_B, MAT_C};
你应该像
那样声明数组float ( *matrices[3] )[4] = {MAT_A, MAT_B, MAT_C};
在这种情况下,函数应该声明为
void get_input( float ( ** matrices)[4] );
并被称为
get_input( matrices );
或
mat *matrices[3] = { &MAT_A, &MAT_B, &MAT_C };
在最后一种情况下,函数像
一样被调用get_input( matrices );
函数get_input
也声明为
void() get_input(mat** matrices);
实际上相当于
void() get_input( float ( ** matrices )[4][4]);
但是在函数
的调用中get_input(&matrices);
参数的类型为
float( * ( * ) [3])[4][4]
变化
mat *matrices[3] = {MAT_A, MAT_B, MAT_C};
mat *matrices[3] = {&MAT_A, &MAT_B, &MAT_C};