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

Does this really break strict-aliasing rules?

When I compile this sample code using g++, I get this warning: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] The code: #include int main() { alignas(int) char data[sizeof(int)]; …
Red Alert
  • 3,786
  • 2
  • 17
  • 24
35
votes
5 answers

GCC Aliasing Checks w/Restrict pointers

Consider the following two snippets: #define ALIGN_BYTES 32 #define ASSUME_ALIGNED(x) x = __builtin_assume_aligned(x, ALIGN_BYTES) void fn0(const float *restrict a0, const float *restrict a1, float *restrict b, int n) { …
Freddie Witherden
  • 2,369
  • 1
  • 26
  • 41
31
votes
1 answer

Has a std::byte pointer the same aliasing implications as char*?

C++ (and C) strict aliasing rules include that a char* and unsigned char* may alias any other pointer. AFAIK there is no analogous rule for uint8_t*. Thus my question: What are the aliasing rules for a std::byte pointer? The C++ reference currently…
maxschlepzig
  • 35,645
  • 14
  • 145
  • 182
30
votes
9 answers

Is the strict aliasing rule incorrectly specified?

As previously established, a union of the form union some_union { type_a member_a; type_b member_b; ... }; with n members comprises n + 1 objects in overlapping storage: One object for the union itself and one object for each union…
fuz
  • 88,405
  • 25
  • 200
  • 352
30
votes
8 answers

What's a proper way of type-punning a float to an int and vice-versa?

The code below performs a fast inverse square root operation by some bit hacks. The algorithm was probably developed by Silicon Graphics in early 1990's and it's appeared in Quake 3 too. more info However I get the following warning from GCC C++…
plasmacel
  • 8,183
  • 7
  • 53
  • 101
29
votes
5 answers

What precautions should I take to make a memory pool that does not invoke undefined behavior?

My initial problem is that I have, on a project, several objects which share a lifetime (i.e., once I free one of them, I'll free them all), then I wanted to allocate a single block of memory. I have arrays of three different object types, struct…
paulotorrens
  • 2,286
  • 20
  • 30
29
votes
1 answer

aligned_storage and strict aliasing

I'm currently using aligned_storage to implement an 'Optional' type similar to that of boost::optional. To accomplish this I have a class member like so: typename std::aligned_storage::value>::type t_; I use…
28
votes
2 answers

Is it undefined behavior to `reinterpret_cast` a `T*` to `T(*)[N]`?

Consider the following scenario: std::array a; auto p = reinterpret_cast(a.data()); (*p)[0] = 42; Is this undefined behavior? I think it is. a.data() returns a int*, which is not the same as int(*)[8] The type aliasing rules on…
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
28
votes
2 answers

Are all pointers derived from pointers to structure types the same?

The Question The question of whether all pointers derived from pointers to structure types are the same, is not easy to answer. I find it to be a significant question for the following two primary reasons. A. The lack of a pointer to pointer to…
Dror K.
  • 1,989
  • 17
  • 26
28
votes
4 answers

Strict aliasing rule and 'char *' pointers

The accepted answer to What is the strict aliasing rule? mentions that you can use char * to alias another type but not the other way. It doesn't make sense to me — if we have two pointers, one of type char * and another of type struct something *…
user3489275
  • 401
  • 4
  • 8
28
votes
4 answers

Why doesn't GCC and Clang do this aliasing-optimization?

I have a case where a friend casts a non-base class object of type "Base" to a class type object "Derived", where "Derived" is a derived class of "Base" and only adds functions, but no data. In the below code, I did add a data member x to the…
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
28
votes
3 answers

Aliasing T* with char* is allowed. Is it also allowed the other way around?

Note: This question has been renamed and reduced to make it more focused and readable. Most of the comments refer to the old text. According to the standard, objects of different type may not share the same memory location. So this would not be…
StackedCrooked
  • 34,653
  • 44
  • 154
  • 278
27
votes
2 answers

When is char* safe for strict pointer aliasing?

I've been trying to understand the strict aliasing rules as they apply to the char pointer. Here this is stated: It is always presumed that a char* may refer to an alias of any object. Ok so in the context of socket code, I can do this: struct…
Doug T.
  • 64,223
  • 27
  • 138
  • 202
27
votes
4 answers

How to cast sockaddr_storage and avoid breaking strict-aliasing rules

I'm using Beej's Guide to Networking and came across an aliasing issue. He proposes a function to return either the IPv4 or IPv6 address of a particular struct: 1 void *get_in_addr( struct sockaddr *sa ) 2 { 3 if (sa->sa_family == AF_INET) 4…
sinoth
  • 7,602
  • 3
  • 19
  • 22
25
votes
5 answers

Reusing a float buffer for doubles without undefined behaviour

In one particular C++ function, I happen to have a pointer to a big buffer of floats that I want to temporarily use to store half the number of doubles. Is there a method to use this buffer as scratch space for storing the doubles, which is also…
André Offringa
  • 362
  • 2
  • 7
1
2
3
37 38