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

Dmi*_*tri 1 c++ gcc qualifiers clang boringssl

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

\n
typedef char *OPENSSL_STRING;\n#if USE_TYPEDEF\n#define constptr const OPENSSL_STRING\n#else\n#define constptr const char *\n#endif\n\nint\nfoo (const void **ap)\n{\n    constptr a = (constptr) *ap;\n    return a != 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我测试了四种场景,如下:

\n
sh$ g++ -c t2.cc -Wignored-qualifiers -DUSE_TYPEDEF\nt2.cc: In function \xe2\x80\x98int foo(const void**)\xe2\x80\x99:\nt2.cc:11:30: warning: type qualifiers ignored on cast result type [-Wignored-qualifiers]\n   11 |     constptr a = (constptr) *ap;\n      |                              ^~\nsh$ g++ -c t2.cc -Wignored-qualifiers \nsh$ clang++ -c t2.cc -Wignored-qualifiers -DUSE_TYPEDEF\nsh$ clang++ -c t2.cc -Wignored-qualifiers \nsh$ \n
Run Code Online (Sandbox Code Playgroud)\n

这是 gcc 中的一个错误——还是还有更多我不明白的事情发生?

\n
\n

供参考:警告位于BoringSSL 的 stack.h 中

\n

son*_*yao 5

给定const OPENSSL_STRING,const在 typedefOPENSSL_STRING本身上被限定,因此类型将是char * const,即const指向非常量的指针char(请注意,它不是const char *)。Gcc 只是想告诉您,作为转换结果,该const部分将被忽略。ie(char * const) *ap;与 具有相同的效果(char *) *ap;

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

const int i = (int) 0;       // a weird conversion
const int i = (const int) 0; // same effect as above
Run Code Online (Sandbox Code Playgroud)

  • @Dmitri 编译器不需要这样做,clang 的行为也是有效的。 (3认同)