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
19
votes
3 answers

Is placement new legally required for putting an int into a char array?

There seems to be some agreement that you can't willy nilly point (an int*) into a char array because of the C++ aliasing rules. From this other question -- Generic char[] based storage and avoiding strict-aliasing related UB -- it seems that it is…
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
19
votes
2 answers

GCC and strict aliasing between arrays of a same type

Context “Strict aliasing”, named after the GCC optimization, is an assumption by the compiler that a value in memory will not be accessed through an lvalue of a type (the “declared type”) very different from the type the value was written with (the…
Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
19
votes
3 answers

C99 strict aliasing rules in C++ (GCC)

As far as I understand, GCC supports all of its C99 features in C++. But how is C99 strict aliasing handled in C++ code? I know that casting with C casts between unrelated types is not strict-aliasing-safe and may generate incorrect code, but what…
Alex B
  • 82,554
  • 44
  • 203
  • 280
19
votes
1 answer

How to implement "_mm_storeu_epi64" without aliasing problems?

(Note: Although this question is about "store", the "load" case has the same issues and is perfectly symmetric.) The SSE intrinsics provide an _mm_storeu_pd function with the following signature: void _mm_storeu_pd (double *p, __m128d a); So if I…
Nemo
  • 70,042
  • 10
  • 116
  • 153
18
votes
3 answers

How to allocate memory for an array and a struct in one malloc call without breaking strict aliasing?

When allocating memory for a variable sized array, I often do something like this: struct array { long length; int *mem; }; struct array *alloc_array( long length) { struct array *arr = malloc( sizeof(struct array) +…
ego
  • 279
  • 1
  • 6
18
votes
4 answers

Is this use of unions strictly conforming?

Given the code: struct s1 {unsigned short x;}; struct s2 {unsigned short x;}; union s1s2 { struct s1 v1; struct s2 v2; }; static int read_s1x(struct s1 *p) { return p->x; } static void write_s2x(struct s2 *p, int v) { p->x=v;} int test(union s1s2…
supercat
  • 77,689
  • 9
  • 166
  • 211
18
votes
3 answers

Why compilers no longer optimize this UB with strict aliasing

One of the first results for strict aliasing on google is this article http://dbp-consulting.com/tutorials/StrictAliasing.html One interesting thing I noticed is this: http://goo.gl/lPtIa5 uint32_t swaphalves(uint32_t a) { uint32_t acopy = a; …
NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
17
votes
2 answers

Once again: strict aliasing rule and char*

The more I read, the more confused I get. The last question from the related ones is closest to my question, but I got confused with all words about object lifetime and especially - is it OK to only read or not. To get straight to the point.…
Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
17
votes
4 answers

How to implement fast inverse sqrt without undefined behavior?

From what I understood about strict aliasing rule, this code for fast inverse square root will result in undefined behavior in C++: float Q_rsqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number *…
Ruslan
  • 18,162
  • 8
  • 67
  • 136
17
votes
1 answer

Understanding restrict qualifier by examples

The restrict keyword's behavior is defined in C99 by 6.7.3.1: Let D be a declaration of an ordinary identifier that provides a means of designating an object P as a restrict-qualified pointer to type T. If D appears inside a block and does not…
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
16
votes
3 answers

Is it legal to reuse memory from a fundamental type array for a different (yet still fundamental) type array

This is a follow up to this other question about memory re-use. As the original question was about a specific implementation, the answer was related to that specific implementation. So I wonder whether, it is legal in a conformant implementation to…
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
16
votes
2 answers

Is there a (semantic) difference between the return value of placement new and the casted value of its operand?

Is there a (semantic) difference between the return value of placement new and the casted value of its operand? struct Foo { ... }; char buffer[...]; Foo *a = new(buffer) Foo; Foo *b = reinterpret_cast(buffer); Does a and b differ in some…
geza
  • 28,403
  • 6
  • 61
  • 135
16
votes
2 answers

Cast array of bytes to POD

Let's say, I have an array of unsigned chars that represents a bunch of POD objects (e.g. either read from a socket or via mmap). Which types they represent and at what position is determined at runtime, but we assume, that each is already properly…
MikeMB
  • 20,029
  • 9
  • 57
  • 102
16
votes
2 answers

Does this code violate the strict aliasing rule?

Questions: Does this code below violate strict aliasing rules? That is, would a smart compiler be allowed to print 00000 (or some other nasty effect), because a buffer first accessed as other type is then accessed via int*? If not, would moving…
hyde
  • 60,639
  • 21
  • 115
  • 176
16
votes
2 answers

C++'s Strict Aliasing Rule - Is the 'char' aliasing exemption a 2-way street?

Just a couple weeks ago, I learned that the C++ Standard had a strict aliasing rule. Basically, I had asked a question about shifting bits -- rather than shifting each byte one at a time, to maximize performance I wanted to load my processor's…
digitale
  • 645
  • 4
  • 13