Ctor初始化程序:自我初始化导致崩溃? [英] Ctor Initializer: self initialization causes crash?

查看:235
本文介绍了Ctor初始化程序:自我初始化导致崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在调试生产中的崩溃时很难。只是想与这里的人们确认语义。我们有一个类... ...

  class Test {
public:
Test()
{
//成员初始化...
m_str = m_str;
}
〜Test(){}
private:
//其它成员...
std :: string m_str;
};

有人更改了初始化以使用ctor初始化列表,这在我们的代码语义中是合理正确的。初始化的顺序和它们的初始值是正确的。所以类看起来像...

  class Test {
public:
Test $ b:/ * other inits ,,, * / m_str(m_str)
{
}
〜Test(){}
private:
//其他成员...
std :: string m_str;
};

但是代码突然开始崩溃了!我隔离了这个代码片段的长列表 m_str(m_str)。我通过链接文字确认了此信息。



坠毁?标准是什么说的? (它是未定义的行为?)

解决方案

第一个构造函数等效于

  Test()
:m_str()
{
//成员初始化...
m_str = m_str;
}

这就是说,到构造函数中的赋值时, code> m_str 已隐式初始化为空字符串。所以赋值给自我虽然完全没有意义和多余,但不会产生任何问题(因为 std :: string :: operator =()



但是,在第二个构造函数中,您尝试初始化 m_str 其本身在初始化列表中 - 此时尚未初始化

更新:对于基本类型,这仍然是未定义的行为(导致一个具有垃圾值的字段),因此,但它不会崩溃(通常 - 见下面的意见例外),因为根据定义的原始类型没有构造函数,析构函数和不包含指向其他对象的指针。



对于不包含具有所有权语义的指针成员的任何类型为true。 std :: string 因此证明不是以下之一: - )


I had a hard time debugging a crash on production. Just wanted to confirm with folks here about the semantics. We have a class like ...

class Test {
public:
  Test()
  {
    // members initialized ...
    m_str = m_str;
  }
  ~Test() {}
private:
  // other members ...
  std::string m_str;
};

Someone changed the initialization to use ctor initialization-lists which is reasonably correct within our code semantics. The order of initialization and their initial value is correct among other things. So the class looks like ...

class Test {
public:
  Test() 
    : /*other inits ,,, */ m_str(m_str)
  {
  }
  ~Test() {}
private:
  // other members ...
  std::string m_str;
};

But the code suddenly started crashing! I isolated the long list of inits to this piece of code m_str(m_str). I confirmed this via link text.

Does it have to crash? What does the standard say about this? (Is it undefined behavior?)

解决方案

The first constructor is equivalent to

  Test()
  : m_str()
  {
    // members initialized ...
    m_str = m_str;
  }

that is, by the time you get to the assignment within the constructor, m_str has already been implicitly initialized to an empty string. So the assignment to self, although completely meaningless and superfluous, causes no problems (since std::string::operator=(), as any well written assignment operator should, checks for self assignment and does nothing in this case).

However, in the second constructor, you are trying to initialize m_str with itself in the initializer list - at which point it is not yet initialized. So the result is undefined behaviour.

Update: For primitive types, this is still undefined behaviour (resulting in a field with garbage value), but it does not crash (usually - see the comments below for exceptions) because primitive types by definition have no constructors, destructors and contain no pointers to other objects.

Same is true for any type that does not contain pointer members with ownership semantics. std::string is hereby demonstrated to be not one of these :-)

这篇关于Ctor初始化程序:自我初始化导致崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆