但是,gcc
如果不发出以下警告,则无法成功编译此代码:
$gcc -ggdb3 -Wall -Wextra -o test test.c
test.c: In function ‘main’:
test.c:16:2: warning: passing argument 1 of ‘Sum2D’ from incompatible pointer type [enabled by default]
printf( "%d\n", Sum2D(array,4) );
^
test.c:4:5: note: expected ‘const int (*)[4]’ but argument is of type ‘int (*)[4]’
int Sum2D(const int ar[][COLS], int rows);
^
1)为什么要警告?
2)我怎样才能消除从将"噪音"?(除了const
以array
声明.)
(如果array
和函数都使用一维数组,则没有警告.)
系统信息:
Ubuntu 14.04LTS
编译器:gcc 4.8.2
M.M..
9
这是C设计中一个不幸的"错误"; T (*p)[N]
不会隐式转换为T const (*p)[N]
.您将不得不使用丑陋的演员表,或者让函数参数不被接受const
.
乍一看,这种转换看起来应该是合法的.C11 6.3.2.3/2:
对于任何限定符q,指向非q限定类型的指针可以转换为指向该类型的q限定版本的指针;
不过也看C11 6.7.3/9(C99中为/ 8):
如果数组类型的规范包含任何类型限定符,则元素类型是限定的,而不是数组类型.
这最后一个引号说,int const[4]
是不是认为是const
的-qualified版本int[4]
.实际上它是一个const
4 const int
秒的非限定数组. int[4]
并且int const[4]
是不同元素类型的数组.
因此6.3.2.3/2实际上不允许int (*)[4]
转换为int const (*)[4]
.
另一个奇怪的情况是,这个问题const
和数组出现的时候是在使用typedef时; 例如:
typedef int X[5];
void func1( X const x );
void func1( int const x[5] );
这会导致编译器错误:X const x
意味着它x
是const,但它指向一个非const int
的数组; 而int const x[5]
means x
不是const,而是指向一个const int数组!
在这里进一步阅读,感谢@JensGustedt
1> M.M..:
这是C设计中一个不幸的"错误"; T (*p)[N]
不会隐式转换为T const (*p)[N]
.您将不得不使用丑陋的演员表,或者让函数参数不被接受const
.
乍一看,这种转换看起来应该是合法的.C11 6.3.2.3/2:
对于任何限定符q,指向非q限定类型的指针可以转换为指向该类型的q限定版本的指针;
不过也看C11 6.7.3/9(C99中为/ 8):
如果数组类型的规范包含任何类型限定符,则元素类型是限定的,而不是数组类型.
这最后一个引号说,int const[4]
是不是认为是const
的-qualified版本int[4]
.实际上它是一个const
4 const int
秒的非限定数组. int[4]
并且int const[4]
是不同元素类型的数组.
因此6.3.2.3/2实际上不允许int (*)[4]
转换为int const (*)[4]
.
另一个奇怪的情况是,这个问题const
和数组出现的时候是在使用typedef时; 例如:
typedef int X[5];
void func1( X const x );
void func1( int const x[5] );
这会导致编译器错误:X const x
意味着它x
是const,但它指向一个非const int
的数组; 而int const x[5]
means x
不是const,而是指向一个const int数组!
在这里进一步阅读,感谢@JensGustedt