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

时间:2018-03-01 18:46:02

标签: c compilation compiler-warnings

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

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

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

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

似乎是说 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 */

背景和杂项

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

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

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

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

我认为这与Strange warning in a C function const multidimensional-array argument或其他人有关,但这里的问题似乎是使用了typedef而不是在强制转换中使用typedef。不过,如果这是重复,我道歉并将其删除。

1 个答案:

答案 0 :(得分:2)

您的问题中的评论者似乎确认了一个编译器错误,事实上@ zowl显然已经检查过错误只发生在 GCC 5.3.0 上,如{{{} 3}}

用户@ in this comment使用了 clang 编译器,它没有生成警告,如liliscent中所述。

所以 GCC 5.3.0 中存在错误的结论似乎是有效的。