Questions tagged [strict-aliasing]

Strict aliasing is an assumption, made by the C or C++ compiler, that de-referencing pointers to objects of different types will never refer to the same memory location (i.e. they will not alias each other).

Strict aliasing is an assumption, made by the C or C++ compiler, that de-referencing pointers to objects of different types will never refer to the same memory location (i.e. they will not alias each other).

Strict aliasing or "the strict aliasing rule" are informal terms. It refers not to one, but to a set of rules regarding type compatibility when accessing a value through pointers.

A "strict aliasing violation" is when a value is accessed through a pointer which is not compatible with the data type. Example:

short array[2];
int* ptr = (int*)array;       // strict aliasing violation
if(*ptr == something)         // therefore, this is undefined behavior

Strict aliasing is explained in detail here: What is the strict aliasing rule?

The reason why the strict aliasing exists is performance, as discussed here. A compiler which assumes that the strict aliasing rule is followed can make various optimizations to increase performance.

Traditionally, not many compilers have done such optimizations, and therefore the undefined behavior caused by strict aliasing violations is a common dormant bug in many programs - a bug that will not surface until the program is ported to a compiler which uses such optimizations.

The GCC compiler in particular is known to frequently do such optimizations. They are automatically enabled with compiler options -O2, -O3 or -Os, or explicitly with -fstrict-aliasing. Strict aliasing optimizations can be disabled with -fno-strict-aliasing. GCC reference.


The aliasing rules are described in the following sections in the standards:

C11 6.5 §7

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the object,
— a type that is the signed or unsigned type corresponding to the effective type of the object,
— a type that is the signed or unsigned type corresponding to a qualified version of the effective 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), or
— a character type.

C++11 3.10 §10.

If a program attempts to access the stored value of an object through a glvalue 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 similar (as defined in 4.4) to 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 elements or nonstatic data members (including, recursively, an element or non-static data 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.

563 questions
16
votes
4 answers

Strict aliasing and memory locations

Strict aliasing prevents us from accessing the same memory location using an incompatible type. int* i = malloc( sizeof( int ) ) ; //assuming sizeof( int ) >= sizeof( float ) *i = 123 ; float* f = ( float* )i ; *f = 3.14f ; this would be illegal…
this
  • 5,229
  • 1
  • 22
  • 51
15
votes
1 answer

Does accessing the first field of a struct via a C cast violate strict aliasing?

Does this code violate strict aliasing? struct {int x;} a; *(int*)&a = 3 More abstractly, is it legal to cast between different types as long as the primitive read/write operations are type correct?
Geoffrey Irving
  • 6,483
  • 4
  • 32
  • 40
15
votes
3 answers

Does dereferencing a char* inhibit strict aliasing optimizations?

Consider the following snippet as an example: *pInt = 0xFFFF; *pFloat = 5.0; Since they are int and float pointers, the compiler will assume they don't alias and can exchange them for example. Now let's assume we spice it up with this: *pInt =…
Calmarius
  • 18,570
  • 18
  • 110
  • 157
15
votes
3 answers

`std::complex[n]` and `T[n*2]` type aliasing

Since C++11 std::complex[n] is guaranteed to be aliasable as T[n*2], with well defined values. Which is exactly what one would expect for any mainstream architecture. Is this guarantee achievable with standard C++ for my own types, say struct…
yuri kilochek
  • 12,709
  • 2
  • 32
  • 59
14
votes
1 answer

Why do compilers miss vectorization here?

Consider the following valarray-like class: #include struct va { void add1(const va& other); void add2(const va& other); size_t* data; size_t size; }; void va::add1(const va& other) { for (size_t i = 0; i < size;…
14
votes
1 answer

Does the aliasing loophole apply to signed characters?

In C++ there is an aliasing loophole which allows the object representation of any object to be read or written through some pointers of character type. Does this apply only to char and unsigned char or also to signed char?
BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
14
votes
3 answers

reinterpret_cast vs strict aliasing

I was reading about strict aliasing, but its still kinda foggy and I am never sure where is the line of defined / undefined behaviour. The most detailed post i found concentrates on C. So it would be nice if you could tell me if this is allowed and…
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
14
votes
3 answers

Is using the result of new char[] or malloc to casted float * is UB (strict aliasing violation)?

Which code of these has UB (specifically, which violates strict aliasing rule)? void a() { std::vector v(sizeof(float)); float *f = reinterpret_cast(v.data()); *f = 42; } void b() { char *a = new char[sizeof(float)]; …
geza
  • 28,403
  • 6
  • 61
  • 135
14
votes
1 answer

Strict aliasing, -ffast-math and SSE

Consider the following program: #include #include #include #include using namespace std; int main() { // 4 float32s. __m128 nans; // Set them all to 0xffffffff which should be NaN. …
Timmmm
  • 88,195
  • 71
  • 364
  • 509
14
votes
1 answer

Does casting a char array to another type violate strict-aliasing rules?

Consider these two functions: int f1() { alignas(int) char buf[sizeof(int)] = {}; return *reinterpret_cast(buf); } int f2() { alignas(int) char buf[sizeof(int)] = {}; char* ptr = buf; return *reinterpret_cast(ptr); } GCC…
14
votes
1 answer

Aliasing with char *, unsigned char * and signed char *

A char * (and qualified variants) may alias anything. Are signed char * and unsigned char * (and their qualified variants) exempt from this? In other words, I've learned it's a good idea to apply restrict to char* function arguments if I don't…
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
14
votes
5 answers

Can a struct alias its own initial and only member?

For example, is this code valid, or does it invoke undefined behavior by violating the aliasing rules? int x; struct s { int i; } y; x = 1; y = *(struct s *)&x; printf("%d\n", y.i); My interest is in using a technique based on this to develop a…
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
14
votes
1 answer

Does removing const from a pointer-to-const obey strict aliasing in C, and refer to the same object?

Does the following code in C have defined behavior? int main() { const int i = 0; return *(int*)(&i); } I ask because 6.5/7 lists "a qualified version of a type compatible with the effective type of the object" as a valid alias. But the…
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
13
votes
2 answers

Is the strict aliasing rule really a "two-way street"?

In these comments user @Deduplicator insists that the strict aliasing rule permits access through an incompatible type if either of the aliased or the aliasing pointer is a pointer-to-character type (qualified or unqualified, signed or unsigned char…
12
votes
1 answer

Can you access the object representation of any object through a char*?

I have stumbled upon a reddit thread in which a user has found an interesting detail of the C++ standard. The thread has not spawned much constructive discussion, therefore I will retell my understanding of the problem here: OP wants to reimplement…
JMC
  • 1,723
  • 1
  • 11
  • 20