clang、gcc 和忽略的限定符:谁是对的?

clang, gcc, and ignored qualifiers: who is right?

我在编译 BoringSSL 时发现了 gcc 和 clang 之间的行为差​​异,并且能够将其缩减为以下测试用例来说明:

typedef char *OPENSSL_STRING;
#if USE_TYPEDEF
#define constptr const OPENSSL_STRING
#else
#define constptr const char *
#endif

int
foo (const void **ap)
{
    constptr a = (constptr) *ap;
    return a != 0;
}

我测试了四种场景如下:

sh$ g++ -c t2.cc -Wignored-qualifiers -DUSE_TYPEDEF
t2.cc: In function ‘int foo(const void**)’:
t2.cc:11:30: warning: type qualifiers ignored on cast result type [-Wignored-qualifiers]
   11 |     constptr a = (constptr) *ap;
      |                              ^~
sh$ g++ -c t2.cc -Wignored-qualifiers 
sh$ clang++ -c t2.cc -Wignored-qualifiers -DUSE_TYPEDEF
sh$ clang++ -c t2.cc -Wignored-qualifiers 
sh$ 

这是 gcc 中的一个错误——还是还有其他我不明白的地方?


供参考:警告是in BoringSSL's stack.h

给定 const OPENSSL_STRINGconst 在 typedef OPENSSL_STRING 本身上是限定的,因此类型将是 char * const,即 const 指向非const char(注意不是const char *)。 Gcc 只是想告诉您,作为转换结果, const 部分被忽略了。即 (char * const) *ap;(char *) *ap;.

具有相同的效果

将类型更改为 int 可能会更清楚。

const int i = (int) 0;       // a weird conversion
const int i = (const int) 0; // same effect as above