表达副作用的Clang警告

Bia*_*sta 12 c++ typeid clang++

给出以下源代码:

#include <memory>
#include <typeinfo>

struct Base {
  virtual ~Base();
};

struct Derived : Base { };

int main() {
  std::unique_ptr<Base> ptr_foo = std::make_unique<Derived>();

  typeid(*ptr_foo).name();

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

并编译它:

clang++ -std=c++14 -Wall -Wextra -Werror -Wpedantic -g -o test test.cpp

环境设置:

linux x86_64
clang version 5.0.0
Run Code Online (Sandbox Code Playgroud)

由于警告(注释-Werror)它不编译:

error: expression with side effects will be evaluated
      despite being used as an operand to 'typeid'
      [-Werror,-Wpotentially-evaluated-expression]
  typeid(*ptr_foo).name();
Run Code Online (Sandbox Code Playgroud)

(请注意:海湾合作委员会并未声称存在这种潜在问题)


有没有办法获得有关a指向的类型的信息unique_ptr而不产生那种警告?

注意:我不是在谈论禁用-Wpotentially-evaluated-expression或避免-Werror.

Art*_*sky 8

看起来以下应该没有警告就可以工作,并为派生类给出正确的结果

std::unique_ptr<Foo> ptr_foo = std::make_unique<Bar>();

if(ptr_foo.get()){
    auto& r = *ptr_foo.get();
    std::cout << typeid(r).name() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

  • 根本没有1线解决方案吗?我在断言中使用了类似的表达式,该表达式仅针对内部构建进行宏处理,因此并不真正想要临时 (3认同)
  • 有什么解释吗?为什么直接 typeid(*ptr_foo.get()).name() 不起作用? (3认同)
  • @eric因为人们大多认为“typeid”不评估表达式。对于返回多态对象的表达式,编译器必须生成代码来计算该表达式。它是有效的 C++ 代码(因此 GCC 不会发出警告),但人们可能不知道后果。当这种情况发生时,Clang 会发出警告。这些解决方案都使表达式求值在 typeid 之外,编译器和人类读者都应该看到这并不奇怪。 (2认同)