Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will accessing a class object through a pointer to its derived class break strict aliasing rules?

Tags:

c++

void foobar(Base* base)
{
    Derived* derived = dynamic_cast<Derived*>(base); // or static_cast
    derived->blabla = 0xC0FFEE;
    if (base->blabla == 0xC0FFEE)
        ...
}

On compilers with strict aliasing, is "derived" an alias for "base"?

like image 796
oba Avatar asked Oct 10 '09 03:10

oba


People also ask

What is the problem of aliasing while using pointers?

Because any pointer could alias any other pointer in C, the compiler must assume that memory regions accessed through these pointers can overlap, which prevents many possible optimizations. C++ enables more optimizations, as pointer arguments will not be treated as possible aliases if they point to different types.

How do you get around strict aliasing?

The answer typically is to type pun, often the methods used violate strict aliasing rules. Sometimes we want to circumvent the type system and interpret an object as a different type. This is called type punning, to reinterpret a segment of memory as another type.

What is the strict aliasing rule and why do we care?

GCC compiler makes an assumption that pointers of different types will never point to the same memory location i.e., alias of each other. Strict aliasing rule helps the compiler to optimize the code.

What is aliasing in C++?

In C, C++, and some other programming languages, the term aliasing refers to a situation where two different expressions or symbols refer to the same object.


1 Answers

Two pointers are aliased whenever it is possible to access the same object through them. Paragraph 3.10/15 of the standard specifies when an access to an object is valid.

If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined:

  • the dynamic type of the object,
  • a cv-qualified version of the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union),
  • a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
  • a char or unsigned char type.

In your case, *derived is either an l-value of the dynamic type of the object or it is of a type that is a base class type of the dynamic type of the object. *base is of a type that is a base class type of the dynamic type of the object.

Therefore, you are allowed to access the object through both derived and base, making the two pointers aliased.

like image 197
avakar Avatar answered Nov 02 '22 23:11

avakar