【问题标题】:clang, gcc, and ignored qualifiers: who is right?clang、gcc 和被忽略的限定符:谁是对的?
【发布时间】:2021-02-26 15:03:19
【问题描述】:

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

【问题讨论】:

  • 您的测试用例中缺少main()
  • 这个宏的存在真是莫名其妙。两个分支是相同的。
  • 警告只是警告......请参阅 C++ 标准,如 n3337 并编写自己的 GCC plugin 以产生更多警告
  • 该宏是来自 BoringSSL 还是完全代表 BoringSSL?它似乎破碎毫无意义。

标签: c++ gcc clang qualifiers boringssl


【解决方案1】:

给定const OPENSSL_STRINGconst 在 typedef OPENSSL_STRING 本身上是合格的,所以类型将是char * 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

【讨论】:

  • 所以宏好像坏了,对吧?或者至少,它不做例如cmets 中的 tadman 直觉地认为/期望它会这样做,并且没有明显的理由让它存在。
  • 哦,我明白了!所以应该抱怨它是clang,但没有。
  • @underscore_d 我不确定 OP 的意图,使用宏或直接使用 const OPENSSL_STRING 会产生相同的结果。
  • @Dmitri 编译器不需要这样做,clang 的行为也是有效的。
猜你喜欢
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多