GCC对const限定词的警告正确吗?

时间:2019-02-03 21:38:55

标签: c gcc language-lawyer

考虑以下代码,该代码源自this question

const int (*foo(const char *a))[1]
    { return (const int (*)[1]) a; }

compiled with GCC 8.2 (and older versions) using -Wcast-qual时,GCC警告:

source>:2:15: warning: cast discards 'const' qualifier from pointer target type [-Wcast-qual]
      { return (const int (*)[1]) a; }
               ^

此警告是否正确?显然,目标类型中包含const限定符。

它是在元素类型上,而不是在指针立即指向的东西上,它是数组类型。但是,即使我们使用typedef int T[1];并用(const T *)替换强制类型转换,警告仍然存在。此外,根据C 2018 6.7.3 10,数组类型上的限定符适用于元素类型,而不适用于数组类型,因此两种类型的类型相同。

Clang不显示此警告。

如果将演员表更改为(const void *)

const int (*foo(const char *a))[1]
    { return (const void *) a; }

然后警告消失。如果将-pedantic添加到编译开关,则会收到有关const的不同警告:

source>:2:15: warning: return discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
      { return (const void *) a; }
               ^~~~~~~~~~~~~~~~

除了警告有关从return表达式到函数return类型的隐式转换,这看起来像是相同的警告,而先前的警告与强制转换中的显式转换有关。但是,这个仅与-pedantic一起出现。为什么?

1 个答案:

答案 0 :(得分:4)

这是GCC bug 81631。由于将限定符应用于实际应用于数组元素的数组的复杂性,GCC无法识别出对指向数组的指针的转换,从而保留了const限定符。