strict-aliasing

C++ strict-aliasing agnostic cast

眉间皱痕 提交于 2019-12-04 11:22:24
I've read lots of QAs about strict aliasing here in Stack Overflow but all they are pretty common and discussion always tends to refer to deep-deep details of C++ standard which are almost always are difficult to understand properly. Especially when standard do not say things directly but describes something in a muddy unclear way. So, my question is probably a possible duplicate of tonns of QAs here, but, please, just answer a specific question: Is it a correct way to do a "nonalias_cast"?: template<class OUT, class IN> inline auto nonalias_cast(IN *data) { char *tmp = reinterpret_cast<char *

gcc: How to use __attribute((__may_alias__)) properly to avoid “derefencing type-punned pointer” warning

守給你的承諾、 提交于 2019-12-04 09:47:36
问题 I've got some code that uses type-punning to avoid having to call a member "object"'s constructor and destructor unless/until it's actually necessary to use the object. It works fine, but under g++ 4.4.3, I get this dreaded compiler warning: jaf@jeremy-desktop:~$ g++ -O3 -Wall puns.cpp puns.cpp: In instantiation of ‘Lightweight<Heavyweight>’: puns.cpp:68: instantiated from here puns.cpp:12: warning: ignoring attributes applied to ‘Heavyweight’ after definition puns.cpp: In destructor

How to legally use type-punning with unions to cast between variations of struct sockaddr without violating the strict aliasing rule?

試著忘記壹切 提交于 2019-12-04 09:25:47
POSIX intends pointers to variations of struct sockaddr to be castable, however depending on the interpretation of the C standard this may be a violation of the strict aliasing rule and therefore UB. (See this answer with comments below it.) I can, at least, confirm that there may at least be a problem with gcc: this code prints Bug! with optimization enabled, and Yay! with optimization disabled: #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> sa_family_t test(struct sockaddr *a, struct sockaddr_in *b) { a->sa_family = AF_UNSPEC; b->sin_family = AF_INET; return a->sa_family;

Do any compilers transfer effective type through memcpy/memmove

↘锁芯ラ 提交于 2019-12-04 05:22:11
According to N1570 6.5/6: If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. That would suggest that even on a system where "long" and some other integer type have the same representation, the following would invoke Undefined Behavior: #if ~0UL == ~0U #define long_equiv int #elif ~0UL == ~0ULL #define long_equiv long

std::launder and strict aliasing rule

好久不见. 提交于 2019-12-04 04:53:05
Consider this code: void f(char * ptr) { auto int_ptr = reinterpret_cast<int*>(ptr); // <---- line of interest // use int_ptr ... } void example_1() { int i = 10; f(reinterpret_cast<char*>(&i)); } void example_2() { alignas(alignof(int)) char storage[sizeof(int)]; new (&storage) int; f(storage); } line of interest with call from example_1: Q1: On the callside the char pointer is aliasing our integer pointer. This is valid. But is it also valid to just cast it back to an int? We know an int is within its lifetime there, but consider the function is defined in another translation unit (with no

reinterpret_cast vs strict aliasing

杀马特。学长 韩版系。学妹 提交于 2019-12-04 04:18:11
I was reading about strict aliasing, but its still kinda foggy and I am never sure where is the line of defined / undefined behaviour. The most detailed post i found concentrates on C. So it would be nice if you could tell me if this is allowed and what has changed since C++98/11/... #include <iostream> #include <cstring> template <typename T> T transform(T t); struct my_buffer { char data[128]; unsigned pos; my_buffer() : pos(0) {} void rewind() { pos = 0; } template <typename T> void push_via_pointer_cast(const T& t) { *reinterpret_cast<T*>(&data[pos]) = transform(t); pos += sizeof(T); }

Aliasing array with pointer-to-struct without violating the standard

大城市里の小女人 提交于 2019-12-04 04:16:11
Reading this I understood that you can alias structures (without violating the standard, that is) if they have compatible members, i.e given the following struct: typedef struct { uint32_t a; uint32_t b; } Frizzly; The following would break aliasing rules: uint32_t foo(uint16_t *i) { Frizzly *f = (Frizzly *)i; return f->a; } But the following would not: uint32_t foo(uint32_t *i) { Frizzly *f = (Frizzly *)i; return f->b; } because the "aggregrate type" in question contains types compatible with the pointer that that we're casting into it, i.e. a pointer to type uint32_t can be casted into a

Is it legal to alias a char array through a pointer to int?

≯℡__Kan透↙ 提交于 2019-12-04 03:14:34
I know that the following is explicitly allowed in the standard: int n = 0; char *ptr = (char *) &n; cout << *ptr; What about this? alignas(int) char storage[sizeof(int)]; int *ptr = (int *) &storage[0]; *ptr = 0; cout << *ptr; Essentially, I'm asking if the aliasing rules allow for a sequence of chars to be accessed through a pointer to another type. I'd like references to the portions of the standard that indicate one way or another if possible. Some parts of the standard have left me conflicted; (3.10.10) seems to indicate it would be undefined behavior on the assumption that the dynamic

Does this pointer casting break strict aliasing rule?

放肆的年华 提交于 2019-12-04 02:52:54
This is the fast inverse square root implementation from Quake III Arena: float Q_rsqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long * ) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what? y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed return y; } I noticed that long int i takes the dereferenced value at the address (cast to a long * ) of float y . The code then performs operations

Why does POSIX contradict the ISO C standards [closed]

痴心易碎 提交于 2019-12-04 02:01:41
问题 Closed . This question is opinion-based. It is not currently accepting answers. Want to improve this question? Update the question so it can be answered with facts and citations by editing this post. Closed 3 years ago . 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