strict-aliasing

How to create an uint8_t array that does not undermine strict aliasing?

家住魔仙堡 提交于 2019-12-05 04:58:31
I recently asked this question: Using this pointer causes strange deoptimization in hot loop The problem was that I was writing to an array of type uint8_t and the compiler treated it as if it could alias with the this pointer of the method (of type struct T* ), because void* and char* (= uint8_t* ) can always alias any other pointer in C++. This behaviour caused a missed optimization opportunity. I want to avoid this, of course. So the question is: Can I declare an uint8_t array that enforces strict aliasing, i.e., that the compiler treats as never aliased with any pointer of another type? I

Is this strict aliasing example correct?

情到浓时终转凉″ 提交于 2019-12-05 01:16:45
I've been reading up on the strict aliasing rules over the last week or so and ran into this article: Understanding C/C++ Strict Aliasing . The article goes through several ways two swap the halves of a 32-bit integer, giving both good examples and ones that violate the strict aliasing rule. I'm having trouble understanding one of the examples, though. This code is described as broken. uint32_t swaphalves(uint32_t a) { a = (a >> 16) | (a << 16); return a; } The reason given is: This version looks reasonable, but you don't know if the right and left sides of the | will each get the original

What is the no-undefined-behavior way of deserializing an object from a byte array in C++11 (or later)?

百般思念 提交于 2019-12-05 01:13:47
To overcome alignment issues, I need to memcpy into a temporary. What type should that temporary be? gcc complains that the following reinterpret_cast will break strict aliasing rules: template <typename T> T deserialize(char *ptr) { static_assert(std::is_trivially_copyable<T>::value, "must be trivially copyable"); alignas(T) char raw[sizeof(T)]; memcpy(raw, ptr, sizeof(T)); return *reinterpret_cast<T *>(raw); } (e.g. when T is "long"). I don't want to define a T, since I don't want to construct a T before overwriting it. In a union, doesn't writing one member then reading another count as

OO Polymorphism in C, aliasing issues?

冷暖自知 提交于 2019-12-05 00:47:46
问题 Me and a colleague are trying to achieve a simple polymorphic class hierarchy. We're working on an embedded system and are restricted to only using a C compiler. We have a basic design idea that compiles without warnings (-Wall -Wextra -fstrict-aliasing -pedantic) and runs fine under gcc 4.8.1. However, we are a bit worried about aliasing issues as we do not fully understand when this becomes a problem. In order to demonstrate we have written a toy example with an 'interface' IHello and two

Does access through pointer change strict aliasing semantics?

风流意气都作罢 提交于 2019-12-05 00:33:06
问题 With these definitions: struct My_Header { uintptr_t bits; } struct Foo_Type { struct My_Header header; int x; } struct Foo_Type *foo = ...; struct Bar_Type { struct My_Header header; float x; } struct Bar_Type *bar = ...; Is it correct to say that this C code ( "case one" ): foo->header.bits = 1020; ...is actually different semantically from this code ( "case two" ): struct My_Header *alias = &foo->header; alias->bits = 1020; My understanding is that they should be different: Case One

In C++, What does “access” mean in the strict aliasing rule?

耗尽温柔 提交于 2019-12-05 00:30:01
3.10/10 says: 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: However, the term "access" is not defined anywhere. In this context does it mean read , or read or modify ? In the C standard it is unambiguously defined as read or modify . However in C++11 it seems to be used with different meanings at different times, for example: 1.9/8: Access to volatile objects are evaluated strictly according to the rules of the abstract machine. Clearly this is meant to be read or modify , however in many other

Can an object have more than one effective type?

房东的猫 提交于 2019-12-04 23:14:20
问题 Consider the following code on a platform where the ABI does not insert padding into unions: union { int xi; } x; x.xi = 1; I believe that the second line exhibits undefined behaviour as it violates the strict aliasing rule: The object referred to by x.xi is the same object as the object referred to by x . Both are the same region of storage and the term object is defined in ISO 9899:2011 §3.15 as: object 1 region of data storage in the execution environment, the contents of which can

C++ strict aliasing when not using pointer returned by placement new

北城以北 提交于 2019-12-04 19:40:50
问题 Can this potentially cause undefined behaviour? uint8_t storage[4]; // We assume storage is properly aligned here. int32_t* intPtr = new((void*)storage) int32_t(4); // I know this is ok: int32_t value1 = *intPtr; *intPtr = 5; // But can one of the following cause UB? int32_t value2 = reinterpret_cast<int32_t*>(storage)[0]; reinterpret_cast<int32_t*>(storage)[0] = 5; char has special rules for strict-aliasing. If I use char instead of uint8_t is it still Undefined Behavior? What else changes?

Generic char[] based storage and avoiding strict-aliasing related UB

烈酒焚心 提交于 2019-12-04 17:42:12
问题 I'm trying to build a class template that packs a bunch of types in a suitably large char array, and allows access to the data as individual correctly typed references. Now, according to the standard this can lead to strict-aliasing violation, and hence undefined behavior, as we're accessing the char[] data via an object that is not compatible with it. Specifically, the standard states: If a program attempts to access the stored value of an object through a glvalue of other than one of the

Efficiently generating byte buffer without breaking strict aliasing

久未见 提交于 2019-12-04 17:14:31
This is such a simple pattern, there has to be a "nice" way of sorting it out. I have a function that needs to generate a dynamically sized byte array containing arithmetic data. // Given that I have a function that kinda looks like this: void dispatch(std::vector<char> data); //Will take possesion of data. // The behavior I want, but this breaks strict aliasing void bad_foo(int c) { std::vector<char> real_data(c * sizeof(float)); float* raw_data = reinterpret_cast<float*>(real_data.data()); //Fill raw_data with usefull stuff... dispatch(std::move(real_data)); } void correct_but_slow_foo(int c