首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无警告/错误地在引用上隐式重新解释cast

无警告/错误地在引用上隐式重新解释cast
EN

Stack Overflow用户
提问于 2018-10-12 15:47:21
回答 1查看 153关注 0票数 3

刚刚发现了一个阴险的崩溃的原因是一个未检查的野生由编译器,而不考虑类型。这是预期的行为还是编译器的错误?

Problem:当涉及类型定义时,可以进行隐式重新解释cast,从而破坏类型系统。

代码语言:javascript
复制
#include <iostream>

template<class A, class B>
inline bool
isSameObject (A const& a, B const& b)
{
  return static_cast<const void*> (&a)
      == static_cast<const void*> (&b);
}


class Wau
  {
    int i = -1;
  };

class Miau
  {
  public:
    uint u = 1;
  };


int
main (int, char**)
{
  Wau wau;
  using ID = Miau &;
  ID wuff = ID(wau);      // <<---disaster

  std::cout << "Miau=" << wuff.u
            << " ref to same object: " <<std::boolalpha<< isSameObject (wau, wuff)
            << std::endl; 
  return 0;
}

我震惊地发现gcc-4.9、gcc-6.3和clang-3.8接受了这段代码,没有任何错误,并产生了以下输出:

代码语言:javascript
复制
Miau=4294967295 ref to same object: true

请注意,我使用了类型构造函数语法ID(wau)。我预计这种行为在C型演员身上,即(ID)wau上。只有当使用新的花括号语法ID{wau}时,我们才会得到预期的错误.

代码语言:javascript
复制
~$ g++ -std=c++11 -o aua woot.cpp

woot.cpp: In function ‘int main(int, char**)’:
woot.cpp:31:21: error: no matching function for call to ‘Miau::Miau(<brace-enclosed initializer list>)’
     ID wuff = ID{wau};
                 ^
woot.cpp:10:7: note: candidate: constexpr Miau::Miau()
 class Miau
       ^~~~
woot.cpp:10:7: note:   candidate expects 0 arguments, 1 provided
woot.cpp:10:7: note: candidate: constexpr Miau::Miau(const Miau&)
woot.cpp:10:7: note:   no known conversion for argument 1 from ‘Wau’ to ‘const Miau&’
woot.cpp:10:7: note: candidate: constexpr Miau::Miau(Miau&&)
woot.cpp:10:7: note:   no known conversion for argument 1 from ‘Wau’ to ‘Miau&&’

不幸的是,由于std::initializer_list的失败,大括号的语法常常是模板繁重的代码中不能使用的。所以对我来说,这是一个严重的问题,因为类型系统的保护实际上在这里崩溃了。

  • 有人能解释一下这种行为背后的原因吗?
  • 这是某种向后兼容性(再次,叹息)吗?
EN

回答 1

Stack Overflow用户

发布于 2018-10-12 16:04:54

可以进行隐式重解释,从而破坏类型系统。 ID wuff = ID(wau);

这不是“含蓄”的重释演员。这是显式类型转换。尽管如此,转换确实不容易被重新解释。具体来说,转换的语法称为“功能样式”。

如果您不确定显式类型转换的类型(是使用函数语法,还是使用C样式语法),那么应该避免使用它。许多人会争辩说,不应该使用显式类型转换。

如果您使用的是static_cast,那么您将一直处于类型系统的保护范围内:

代码语言:javascript
复制
ID wuff = static_cast<ID>(wau);

error: non-const lvalue reference to type 'Miau' cannot bind to a value of unrelated type 'Wau'

简单地依赖隐式转换通常也是安全的:

代码语言:javascript
复制
ID wuff = wau;

error: non-const lvalue reference to type 'Miau' cannot bind to a value of unrelated type 'Wau'

这是故意的行为吗

是。

还是编译器的错误?

不是的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52782967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档