How can a C ++ compiler optimize a wrong hierarchical downgrade to cause real undefined behavior

Consider the following example:

class Base {
public:
    int data_;
};

class Derived : public Base {
public:
    void fun() { ::std::cout << "Hi, I'm " << this << ::std::endl; }
};

int main() {
    Base base;
    Derived *derived = static_cast<Derived*>(&base); // Undefined behavior!

    derived->fun(); 

    return 0;
}

A function call is obviously undefined behavior according to the C ++ standard. But on all available machines and compilers (VC2005 / 2008, gcc on RH Linux and SunOS) it works fine (prints "Hello!"). Does anyone know how this code may work incorrectly? Or maybe a more complex example with the same idea (note that Derived should not have any additional data)?

Update:

From standard 5.2.9 / 8:

" cv1 B", B - , rvalue " cv2 D", D ( 10) B, " D" " B" (4.10), cv2 - cvqualification as, cvqualification, cv1, B D. (4.10) . r " cv1 B" B, D, D. undefined.

9.3.1 ( @Agent_L):

- X X , X, undefined.

, .

+3
6

fun() , this, , , . , () this. , undefined ( ).

+9

.

Derived *derived = static_cast<Derived*>(&base);
derived->fun(); // Undefined behavior!

:

Derived *derived = static_cast<Derived*>(&base);  // Undefined behavior!
derived->fun(); // Uses result of undefined behavior

undefined static_cast. undefined. undefined - . .

, . static_cast. . , , .

. - , Base Derived. Derived::fun() , .

, , , . - undefined . undefined.

+5

, , , , .

, undefined (UB) , , ; , 1 , 2 , 10 , . UB , , .

+3

, , , . "this" - , .

class Base
{
public:
    int data_;
};

class Derived : public Base
{

};


void fun(Derived* pThis) 
{
::std::cout << "Hi, I'm " << pThis << ::std::endl; 
}

//because you're JUST getting numerical value of a pointer, it can be same as:
void fun(void* pThis) 
{
    ::std::cout << "Hi, I'm " << pThis << ::std::endl; 
}

//but hey, even this is still same:
void fun(unsigned int pThis) 
{
    ::std::cout << "Hi, I'm " << pThis << ::std::endl; 
}

: . NULL - , . undefined, .

//Edit: ok, , . ((Derived *) NULL) → (); UB. . " , , , ".

+1

, . :

if(some_very_complex_condition)
{
  // here is your original snippet:

  Base base;
  Derived *derived = static_cast<Derived*>(&base); // Undefined behavior!

  derived->fun(); 
}

(1) undefined

(2) , undefined

( , ) _some_very_complex_condition_ . , .

[edit] , , "" UB:

x86 GCC ?

+1

, , , , , , release/ . , , (, ), .

( " , Derived " ) . , .

:

class Base {
public:
    int data_;
    virtual void bar() { std::cout << "Base\n"; }
};

class Derived : public Base {
public:
    void fun() { ::std::cout << "Hi, I'm " << this << ::std::endl; }
    virtual void bar() { std::cout << "Derived\n"; }
};

int main() {
    Base base;
    Derived *derived = static_cast<Derived*>(&base); // Undefined behavior!

    derived->fun(); 
    derived->bar();
}

vtable Base::bar(), , bar() . , Derived Derived, fun, vtable Derived::bar(). , .

, Undefined : , UB, .

+1

All Articles