简体   繁体   中英

is this undefined behavior?

I found the following code in our codebase. My colleague thinks that it's ok but it seems suspiciously like UB. Is it UB or not?

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]) );
   }

}

That is undefined behavior. The real object, inside the original vector, is an A , not a B , so the cast is incorrect and you will get undefined behavior.

The most common result from that code would be either incorrect data (the members of B not present in A are read from the next object in the vector if present, or from the following memory locations) or a crash (if it happens to be the last element, there was no extra space reserved in the original vector and the read happen to extend to a memory page that is protected.

Short answer - yes, it's undefined behavior.

Removing the vectors makes this clearer:

void foo( A a ) {
  B b;
  b = *(B*)(&a);
  a = *(A*)(&b);
}

The above version is equivalent to yours in terms of the memory issues involved. The last statement - the assignment to a - is actually fine. It's a polymorphic upcast, and in fact you don't even need all the extra casting. This is fine:

a = *&b;

The first assignment - to b - is undefined. You are trying an illegal polymorphic downcast. This may be harmless, and all the extra casting will force the compiler to accept it. But it is definitely undefined behavior.

In general if you are using C-style casts with C++ classes, you're in trouble. The right way to try this type of downcast is with dynamic_cast:

b = *(dynamic_cast<B*>(&a));

However this will fail at run-time because &a is not a B* , and in fact, my compiler gives a warning that what I'm doing is ridiculous:

warning: dynamic_cast of 'A a' to 'class B*' can never succeed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM