Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the strict aliasing rules when casting *from* a char array?

I'm confused by the strict aliasing rules when it comes to casting a char array to other types. I know that it is permitted to cast any object to a char array, but I'm not sure what happens the other way around.

Take a look at this:

#include <type_traits>

using namespace std;

struct{
    alignas (int) char buf[sizeof(int)]; //correct?
} buf1;

alignas(int) char buf2[sizeof(int)]; //incorrect?

struct{
    float f; //obviously incorrect
} buf3;

typename std::aligned_storage<sizeof(int), alignof(int)>::type buf4; //obviously correct

int main()
{
    reinterpret_cast<int&>(buf1) = 1;
    *reinterpret_cast<int*>(buf2) = 1;
    reinterpret_cast<int&>(buf3) = 1;
    reinterpret_cast<int&>(buf4) = 1;
}

Compiling using g++-5.3.0 results in warnings only on the second and third line of main:

$ g++ -fsyntax-only -O3 -std=c++14 -Wall main.cpp 
main.cpp: In function ‘int main()’:
main.cpp:25:30: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
  *reinterpret_cast<int*>(buf2) = 1;
                              ^
main.cpp:26:29: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
  reinterpret_cast<int&>(buf3) = 1;
                             ^

Is gcc correct in that lines 1 and 4 are correct, while lines 2 and 3 are not? I'm fairly sure line 4 is correct (that's what aligned_storage is for), but what are the rules at play here?

like image 450
user697683 Avatar asked May 18 '16 14:05

user697683


People also ask

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.

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 pointer aliasing?

Pointer aliasing is a hidden kind of data dependency that can occur in C, C++, or any other language that uses pointers for array addresses in arithmetic operations. Array data identified by pointers in C can overlap, because the C language puts very few restrictions on pointers.

What is C++ aliasing?

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

First of all, absence of warning is not a guarantee of correctness! gcc is getting better and better at spotting problematic code, but it is still not a static analyzing tool (and those are not perfect either!)

Second of all, yes, you are not allowed to access char array through a pointer to other type.

like image 178
SergeyA Avatar answered Nov 15 '22 01:11

SergeyA