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

问题描述 投票:9回答:1

为什么使用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]}’

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

Minimal C code test case

/* 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 */

Background and miscellany

我知道我可以通过[-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。不过,如果这是重复,我道歉并将删除它。

c compilation compiler-warnings
1个回答
2
投票

您的问题中的评论者似乎确认了一个编译器错误,事实上@zowl显然已经检查过该错误只发生在GCC 5.3.0中,正如in this comment所解释的那样。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.