strict-aliasing

Strict aliasing rule

随声附和 提交于 2019-12-01 17:54:36
I'm reading notes about reinterpret_cast and it's aliasing rules ( http://en.cppreference.com/w/cpp/language/reinterpret_cast ). I wrote that code: struct A { int t; }; char *buf = new char[sizeof(A)]; A *ptr = reinterpret_cast<A*>(buf); ptr->t = 1; A *ptr2 = reinterpret_cast<A*>(buf); cout << ptr2->t; I think these rules doesn't apply here: T2 is the (possibly cv-qualified) dynamic type of the object T2 and T1 are both (possibly multi-level, possibly cv-qualified at each level) pointers to the same type T3 (since C++11) T2 is an aggregate type or a union type which holds one of the

Why does POSIX contradict the ISO C standards [closed]

核能气质少年 提交于 2019-12-01 11:06:50
See http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/socket.h.html ( http://pubs.opengroup.org/onlinepubs/9699919799 is from Issue 7 - from 2013 and still the same!) sockaddr_storage is meant to be cast to other structure types, but that contradicts the ANSI and ISO C standards aliasing rules as far as I can tell. (Objects may not be accessed through pointers to incompatible types, with the exception that anything can be accessed through the 3 char types and that the structure and its first member are interchangeable.) I know that that practice of working with sockets existed long

What happened to the “aggregate or union type that includes one of the aforementioned types” strict aliasing rule?

这一生的挚爱 提交于 2019-12-01 06:28:19
问题 Previously, in basic.lval, there was this bullet point: an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union), In the current draft, it is gone. There is some background information at WG21's site: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1359r0.html#2051: The aliasing rules of 7.2.1 [basic.lval] paragraph 10 were

Does reinterpret_casting std::aligned_storage* to T* without std::launder violate strict-aliasing rules? [duplicate]

南笙酒味 提交于 2019-12-01 01:08:48
This question already has an answer here: Does this really break strict-aliasing rules? 2 answers The following example comes from std::aligned_storage page of cppreference.com: #include <iostream> #include <type_traits> #include <string> template<class T, std::size_t N> class static_vector { // properly aligned uninitialized storage for N T's typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N]; std::size_t m_size = 0; public: // Create an object in aligned storage template<typename ...Args> void emplace_back(Args&&... args) { if( m_size >= N ) // possible error handling throw

easy struct inheritance & pseudo-polymorphism vs strict aliasing

浪子不回头ぞ 提交于 2019-11-30 20:40:17
If anybody answers my question, please don't tell me to use C++ . So, I'm making a small library in C that uses an object-oriented approach. I chose to use the less-common of the two main approaches to inheritance in C: copying the members of the base type to the beginning of the derived type. Something like this: struct base { int a; int b; char c; }; struct derived { int a; int b; char c; unsigned int d; void (*virtual_method)(int, char); }; This approach is less popular than the other one (an instance of the base type as the first member of the derived type) because technically, there is no

Does Visual C++ support “strict aliasing”?

五迷三道 提交于 2019-11-30 20:05:19
I recently was surprised to learn that the C and C++ language standards have a "strict aliasing" rule. In essence, the rule prohibits variables of differing types from referencing the same memory location. As an example: char buffer[4] = { 0x55, 0x66, 0x77, 0x88 }; int32 *p = (int32*)&buffer[0]; // illegal because buffer[0] and *p are different types Most of the professional C++ developers I interact with are not familiar with this rule. Based on my research, it seems to affect mostly GCC/G++/CLANG users. Does Visual C++ support enabling/disabling this rule? If so, how does one do so? Thank

How to implement fast inverse sqrt without undefined behavior? [duplicate]

六月ゝ 毕业季﹏ 提交于 2019-11-30 17:28:06
This question already has an answer here: What's a proper way of type-punning a float to an int and vice-versa? 7 answers 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 * 0.5F; y = number; i = * ( long * ) &y; // type punning i = 0x5f3759df - ( i >> 1 ); y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); return y; } Does this code indeed cause UB? If yes, how can it be reimplemented in standard

Casting between primitive type pointers

我怕爱的太早我们不能终老 提交于 2019-11-30 17:08:22
问题 Is the following well-defined: char* charPtr = new char[42]; int* intPtr = (int*)charPtr; charPtr++; intPtr = (int*) charPtr; The intPtr isn't properly aligned (in at least one of the two cases). Is it illegal just having it there? Is it UB using it at any stage? How can you use it and how can't you? 回答1: First, of course: the pointer is guaranteed to be aligned in the first case (by §5.3.4/10 and §3.7.4.1/2), and may be correctly aligned in both cases. (Obviously, if sizeof(int) == 1 , but

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

随声附和 提交于 2019-11-30 12:33:43
问题 Consider the following scenario: std::array<int, 8> a; auto p = reinterpret_cast<int(*)[8]>(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 cppreference seem to suggest that the reinterpret_cast is not valid As a programmer, I know that the memory location pointed by a.data() is an array of 8 int objects Is there any rule I am missing that makes this reinterpret_cast valid? 回答1: An

Understanding restrict qualifier by examples

大兔子大兔子 提交于 2019-11-30 11:31:17
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 have storage class extern, let B denote the block. If D appears in the list of parameter declarations of a function definition, let B denote the associated block. Otherwise, let B denote the block of main (or the block of whatever function is called at program startup in a freestanding environment). In what follows, a pointer expression E is said to be