gcc 6.1.0分段错误 - gcc bug?

时间:2016-07-13 12:54:39

标签: c++ gcc gcc6

让我们考虑以下代码。事实上,这是我使用gmock和mocking void(void)方法找到的缩小的问题。

class Base {
 public:
  virtual ~Base() {}
};

class Derived : public Base
{
 public:
  void GetValueAndDelete()  { delete this; } //here we crash
};

int main() {
  Derived* p = 0;
  p->GetValueAndDelete();
}

使用以下方式构建它:

/tools/gcc6.1/bin/g++ --version
g++ (GCC) 6.1.0

优化级别与-O0不同并运行结果会导致分段错误。

是gcc bug还是带有c ++代码的东西(是的,是的,我知道它使用副作用,但它可以与其他编译器一起使用,也没有优化)

3 个答案:

答案 0 :(得分:4)

  

是gcc bug

没有

  

或带有c ++代码的东西

是。您可以在不指向有效对象的指针上使用箭头运算符。这有不明确的行为。

  

以这种不使用任何成员的方式解除引用空指针和调用方法很好。

根据标准,它不是罚款。它的UB。

  

什么是指针调用方法?

具体是实施。

  

删除这个并不特别。

删除this非常特别。

  

之后,你应该只照顾不使用任何会员

是的,必须确保仅使用new来创建调用该函数的所有实例。没有自动对象,没有静态对象new[],没有malloc +展示位置。

是的,你可以 delete this,但要小心。

答案 1 :(得分:2)

你的直觉似乎是:

  1. p->没问题,因为它只是填写this的语法。
  2. delete this没问题,因为您在this之后没有使用delete
  3. 但上面可能实际上并不行,因为取消引用空指针总是未定义的行为。如果没有启用优化,这可能不会造成任何麻烦,因为编译器正在进行基本编译"当你在脑海里编译时,这有点与你想象的相符。"然而,通过优化,GCC将做很多通常不会做的事情,比如不打扰发出"纠正"面对不正确的源代码时的说明。当你说p->作为你的节目的第一幕时,根本不需要做任何事情 - 它可能只是假装main()是空的(或者崩溃,如同在你的情况下)。

答案 2 :(得分:0)

我知道nullptr上的调用方法是不合标准的,但到目前为止,我还没有看到编译器无法用所描述的方式处理它。似乎gcc6.1的工作方式不同(仍然按照规范)。所以这是gmock bug。我想知道有多少其他项目依赖于这种编译器行为:)

值得一提的是,该方法被称为“这个方法”。内部按预期为零,然后删除失败。我查看了程序集中有一个mov(%rax),%rbx因为rax包含零而失败。