这种未定义的行为?

lez*_*lon 1 c++ undefined-behavior

我在代码库中找到了以下代码.我的同事认为这没关系,但看起来像UB一样可疑.是不是UB?

class A {
   //some stuff
};

class B : public A {
   int a;
   int b;
   int c;
}

void foo( std::vector<A>& a ) {

   std::vector<B> b;
   for(size_t i = 0 ; i < a.size(); ++i ){
      b.push_back( *(B*)(&a[i]) );
   }

   //remove some elements from b

   for(size_t i = 0 ; i < b.size(); ++i ){
      a.push_back( *(A*)(&b[i]) );
   }

}
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 6

这是未定义的行为.原始向量中的真实对象是a A,而不是a B,因此强制转换是不正确的,您将获得未定义的行为.

该代码最常见的结果是不正确的数据(B不存在的成员A从向量中的下一个对象(如果存在)或从以下内存位置读取)或崩溃(如果它恰好是最后一个元素) ,原始向量中没有保留额外空间,并且读取恰好扩展到受保护的内存页面.

  • @JoachimIsaksson:嗯,根据手头的标准,它是UB.如果指针不引用派生对象的基础子对象,则从指向base的指针到指向派生的指针的`static_cast`是未定义的.5.2.9p11*[...]如果"指向cv1 B的指针"类型的prvalue指向实际上是D类型对象的子对象的B,则生成的指针指向类型D的封闭对象.否则,演员的结果未定义.* (4认同)
  • @JoachimIsaksson:在上面的代码中,隐式定义了复制构造函数,它*将*尝试复制.在另一种情况下,您可能会实现一个不会触及这些成员的复制构造函数,但至少可以说这些尴尬......为什么这些成员不重要?如果你想支持从`A`对象进行复制,你可以实现一个带有'A`的构造函数. (3认同)