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_STRING
,const
在 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
我在编译 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_STRING
,const
在 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