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
0
votes
2 answers

(How) can I cast between an aggregate type with one member and that member's type?

Is it possible to do this? struct compound_type { int member; }; void func() { compound_type foo {384}; int bar = sole_member_type_cast(foo); // doesn't compile; there's no such thing …
0
votes
0 answers

Restrict qualifier on class member pointers

I've a program like this, where I've to abstract pointers using a class. I'd like the compiler to optimize the unrolled loop in the main function below assuming no pointer aliasing. How can I effectively use __restrict construct in this scenario?…
vb000
  • 81
  • 1
  • 5
0
votes
2 answers

custom optional breaks strict aliasing rules

I wrote a custom optional class (since I am forced to use C++98 without STL). It looks like this: template struct optional { char value[sizeof(T)]; bool has_value; T& operator*() { return…
0
votes
0 answers

Why do I get a warning: dereferencing type-punned pointer when the pointer has the correct type?

main.cpp : #include "timer.hpp" int main() { TCC_TIMER<0> speed_timer; TC_TIMER<3, TIMER_16BIT> update_timer; speed_timer = TCC_TIMER<0>::Instance(); update_timer = TC_TIMER<3, TIMER_16BIT>::Instance(); for(;;); } timer.hpp…
eijkel
  • 1
  • 1
0
votes
2 answers

c - correct struct element pointer arithmetic

I'm newbie C programmer working on maintaining some legacy embedded C code that looks problematic. In the following snippets I have simplified: UINT16 adcFunc(UINT8 adc, UINT8 channel) { ADC_t* adc_ptr = (ADC_t*)(adc << 4); ADC_CH_t*…
Nubcake
  • 449
  • 1
  • 8
  • 21
0
votes
0 answers

Read word value (hex) of float

Say I have a float I'd like to get the word value of: float f = 42.0f; // 0xDEADBEEF There are two options I know of. Type-pun with std::cout << *(int*)&f; This is undefined behavior, and I don't care to use a char* as an exception (as shown…
0
votes
1 answer

Strict aliasing and casting union pointers

I have looked around this site to try to figure out if my use of casting to different unions is violating strict aliasing or otherwise UB. I have packets coming in on a serial line and I store/get them like: union uart_data { struct { uint8_t…
evading
  • 3,032
  • 6
  • 37
  • 57
0
votes
0 answers

Undefined behavior of member function call through wrong pointer type

Consider the program #include struct A { }; struct B { void f() { std::cout << "Hello world!\n"; }; }; static_assert(alignof(A) == alignof(B)); int main() { A a; reinterpret_cast(&a)->f(); }; Note that the value of a…
walnut
  • 21,629
  • 4
  • 23
  • 59
0
votes
3 answers

Casting uint64_t on bitfield

I found code where bitfield is used for network messages. I would like to know what casting bitfield_struct data = *(bitfield_struct *)&tmp; exaclty does and how it's syntax work. Won't it violate the strict aliasing rule? Here is part of…
Rafael
  • 25
  • 5
0
votes
0 answers

Is passing a pointer of structure of std::uint16_t as a pointer of std::uint16_t undefined behavior?

I am working with a code that does something like that: #include #include static constexpr int TOOL_COUNT = 3; struct Parameters { std::uint16_t version; std::uint16_t delay; std::uint16_t…
0
votes
4 answers

Does Clang misunderstand the 'const' pointer specifier?

In the code below I saw that clang fails to perform better optimisation without implicit restrict pointer specifier: #include #include #include typedef struct { uint32_t event_type; uintptr_t …
0
votes
1 answer

When to use __declspec(noalias)?

As I understood if (https://learn.microsoft.com/en-us/cpp/cpp/noalias?view=vs-2019) __declspec(noalias) means that the function only modifies memory inside her body or through the parameters, so its not modifying static variables, or memory throught…
0
votes
3 answers

Does the following violates strict aliasing

Consider the following code: *((unsigned int*)((unsigned char *)0x400000)); Does it violate strict aliasing? From the strict aliasing rule: An object shall have its stored value accessed only by an lvalue expression that has one of the following…
izac89
  • 3,790
  • 7
  • 30
  • 46
0
votes
1 answer

Default type for object pointed by an integer constant

Given a memory address of ADDR_X where I have dedicated hw registers with some values, does address type-casting it will violate strict aliasing? //lets use some arbitrary address for the sake of this example #define ADDR_X 0xE0F0 void…
izac89
  • 3,790
  • 7
  • 30
  • 46
0
votes
2 answers

Accessing pointer variable as a pointer to a different type in C

Is it good practice to access a pointer variable by dereferencing a pointer to a pointer, which points to a different type or void? Could this break strict aliasing rules? C and C++ have some differences in aliasing rules. In this question we focus…
cmdLP
  • 1,658
  • 9
  • 19