strict-aliasing

Does this pointer casting break strict aliasing rule?

早过忘川 提交于 2019-12-05 19:16:23
问题 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

Why are no strict-aliasing warnings generated for this code?

假装没事ソ 提交于 2019-12-05 18:48:48
I have the following code: struct A { short b; }; struct B { double a; }; void foo (struct B* src) { struct B* b = src; struct A* a = (struct A*)src; b->a = sin(rand()); if(a->b == rand()) { printf("Where are you strict aliasing warnings?\n"); } } I'm compiling the code with the following command line: gcc -c -std=c99 -Wstrict-aliasing=2 -Wall -fstrict-aliasing -O3 foo.c I'm using GCC 4.5.0. I expected the compiler to print out the warning: warning: dereferencing type-punned pointer will break strict-aliasing rules But it never is. I can get the warning to be printed out for other cases, but I

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

纵然是瞬间 提交于 2019-12-05 17:16:41
问题 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

Do the c++11 strict alias rules allow accessing uint64_t via char *, char(&)[N],even std::array<char, N>& with -fstrict-aliasing -Wstrict-aliasing=2?

人盡茶涼 提交于 2019-12-05 15:53:53
According to this stackoverflow answer about C++11/14 strict alias rules: 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

Strict aliasing in Rust?

情到浓时终转凉″ 提交于 2019-12-05 15:17:00
问题 My understanding is that the following code has undefined behaviour in C++ due to something called "strict aliasing rule". #include <cstdint> enum Foo : int16_t {}; void test(Foo& foo) { reinterpret_cast<int16_t&>(foo) = 42; } In particular, a C++ compiler may omit the assignment altogether because it is allowed to assume that the int16_t& returned by the reinterpret_cast doesn't point to the same memory as foo (of type Foo& ) because their types are different. My question is, does Rust have

Strict-aliasing and pointer to union fields

旧城冷巷雨未停 提交于 2019-12-05 11:56:02
I've got a question about strict-aliasing rules, unions and standard. Assume we have the following code: #include <stdio.h> union { int f1; short f2; } u = {0x1}; int * a = &u.f1; short * b = &u.f2; int main() { u.f1 = 1; *a += 1; u.f2 = 2; *b *= 2; printf( "%d %hd\n", *a, *b); return 0; } Now let's look how it works: $ gcc-5.1.0-x86_64 t.c -O3 -Wall && ./a.out 2 4 $ gcc-5.1.0-x86_64 t.c -O3 -Wall -fno-strict-aliasing && ./a.out 4 4 We can see that strict-aliasing breaks dependencies. Moreover it seems to be a correct code without breaking strict-aliasing rule. Does it turn out than in case of

Can we access a member of a non-existing union?

你。 提交于 2019-12-05 09:32:27
In the c++ standard, in [basic.lval]/11.6 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:[...] 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),[...] This sentence is part of the strict-aliasing rule. Can it allow us to access the inactive member of a non existing union? As in: struct A{ int id :1; int value :32; }; struct

What are the strict aliasing rules when casting *from* a char array?

╄→尐↘猪︶ㄣ 提交于 2019-12-05 07:55:24
I'm confused by the strict aliasing rules when it comes to casting a char array to other types. I know that it is permitted to cast any object to a char array, but I'm not sure what happens the other way around. Take a look at this: #include <type_traits> using namespace std; struct{ alignas (int) char buf[sizeof(int)]; //correct? } buf1; alignas(int) char buf2[sizeof(int)]; //incorrect? struct{ float f; //obviously incorrect } buf3; typename std::aligned_storage<sizeof(int), alignof(int)>::type buf4; //obviously correct int main() { reinterpret_cast<int&>(buf1) = 1; *reinterpret_cast<int*>

Is it okay for int** and const int** to alias?

喜夏-厌秋 提交于 2019-12-05 05:18:51
It is my understanding that something like this is okay: const int ci = 42; const int *cip = &ci; int *ip = (int *)cip; int j = *ip; What about this? const int ci = 42; const int *cip = &ci; const int **cipp = &cip; int **ipp = (int **)cipp; int j = **ipp; The expression *ipp is an lvalue of type int * , however it is being used to access an object of effective type const int * . (Namely, cip ). According to the letter of the standard, it is a strict aliasing violation: the list of allowed types to alias does not include aliasing T * as const T * or vice versa. The closest exception is this

C overcoming aliasing restrictions (unions?)

寵の児 提交于 2019-12-05 05:13:44
Assume I have a sample source file, test.c, which I am compiling like so: $ gcc -03 -Wall test.c looks something like this .. /// CMP128(x, y) // // arguments // x - any pointer to an 128-bit int // y - any pointer to an 128-bit int // // returns -1, 0, or 1 if x is less than, equal to, or greater than y // #define CMP128(x, y) // magic goes here // example usages uint8_t A[16]; uint16_t B[8]; uint32_t C[4]; uint64_t D[2]; struct in6_addr E; uint8_t* F; // use CMP128 on any combination of pointers to 128-bit ints, i.e. CMP128(A, B); CMP128(&C[0], &D[0]); CMP128(&E, F); // and so on let's also