为什么在转换const双索引参数时会得到-Wincompatible-pointer-types警告

Bri*_*ich 9 c compilation compiler-warnings

为什么使用gcc5(5.3.0)编译下面的最小测试用例C代码会对带有const参数的warning()函数调用生成[-Wincompatible-pointer-types]警告,并使用ConstMyDouble typedef强制转换该参数,但是不是对于不使用ConstMyDouble转换的nowarning()调用,也不是对使用非const typedef MyDouble的noconst()调用,以及如何修复它?

当在constdef中使用[const]并且使用typedef将参数强制转换为函数时,似乎有一种微妙之处.

最令人困惑的部分是警告信息:

minimal.c:17:7: note: expected ‘const double (*)[2]’ but argument is
  of type ‘const ConstMyDouble (*)[2] {aka const double (*)[2]}’
Run Code Online (Sandbox Code Playgroud)

这似乎是说const double(*)[2]与(又名)const double(*)[2]不一样

最小的C代码测试用例

/* Usage:
 *
 *   ./minimal ; echo ${PIPESTATUS[0]}
 *     => echo command will output 99 (BASH)
 *
 * Compile and link, default:
 *
 *   gcc5 minimal.c -o minimal
 *     => Casts argument to minimal to [ConstMyDouble], a typedef
 *     => Generates [-Wincompatible-pointer-types] warnings
 *
 */
typedef       double      MyDouble;
typedef const double ConstMyDouble;

int   noconst(      MyDouble matrix[2][2] ) { return 32; }
int   warning( ConstMyDouble matrix[2][2] ) { return 33; }
int nowarning( ConstMyDouble matrix[2][2] ) { return 34; }

int main() {
MyDouble matrix[4];
  return   noconst((     MyDouble (*)[2])(matrix))  /* No warning */
       + nowarning(( const double (*)[2])(matrix))  /* No warning */
       +   warning((ConstMyDouble (*)[2])(matrix))  /* Warning */
Run Code Online (Sandbox Code Playgroud)

背景和杂项

我知道我可以通过[-Wincompatible-pointer-type]选项关闭警告,但这是一个最小的测试用例,并不代表我在实践中遇到的情况.

实际上,这些警告只是因为我使用的库(https://naif.jpl.nasa.gov/)中类似的typedef和强制转换而发生,所以我想知道如何解决这个问题,以减少噪音,看到这样的来自我自己的代码的警告.

我正在使用GCC 5.3.0; GCC 4.4.7不会出现这些警告.

这只是一个最小的测试用例; noconst(),nowarning()和warning()函数对参数不做任何事都无关紧要.

我认为这与C函数const多维数组参数中的奇怪警告有关,或者可能与其他人有关,但这里的问题似乎是使用typedef而不是在强制转换中使用typedef.不过,如果这是重复,我道歉并将删除它.

Iha*_*imi 2

正如您问题中的评论者所确认的那样,似乎存在一个编译器错误,事实上 @zowl显然检查了该错误仅在GCC 5.3.0中发生,如本评论中所述。

用户@liliscent使用了clang编译器,并且它也没有生成警告,正如其他评论中所解释的那样。

因此, GCC 5.3.0中存在错误的结论似乎是有效的。