strict-aliasing

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

拈花ヽ惹草 提交于 2019-12-22 08:36:40
问题 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

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

别来无恙 提交于 2019-12-22 06:45:30
问题 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

Opposite keyword of “restrict” in C?

冷暖自知 提交于 2019-12-22 05:43:10
问题 Since strict aliasing may help compiler optimize better, C99 introduced the restrict keyword which can be used as a qualifier of a variable if programmers guarantee that it won't be accessed through a pointer to a different type. However, typecasting between different types is inevitable for several reasons and this will make compiler assume that one pointer is not an alias of the other. Therefore, the workaround method is to disable the global strict aliasing optimization by passing -fno

C overcoming aliasing restrictions (unions?)

☆樱花仙子☆ 提交于 2019-12-22 05:04:24
问题 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

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

戏子无情 提交于 2019-12-22 04:32:39
问题 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; 回答1: 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

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

本秂侑毒 提交于 2019-12-22 03:15:23
问题 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

Why compilers no longer optimize this UB with strict aliasing

我是研究僧i 提交于 2019-12-22 01:42:29
问题 One of the first results for strict aliasing on google is this article http://dbp-consulting.com/tutorials/StrictAliasing.html One interesting thing I noticed is this: http://goo.gl/lPtIa5 uint32_t swaphalves(uint32_t a) { uint32_t acopy = a; uint16_t* ptr = (uint16_t*)&acopy; uint16_t tmp = ptr[0]; ptr[0] = ptr[1]; ptr[1] = tmp; return acopy; } is compiled to swaphalves(unsigned int): mov eax, edi ret by GCC 4.4.7. Any compiler newer than that (4.4 is mentioned in the article so article is

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

孤街醉人 提交于 2019-12-21 17:32:54
问题 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

std::launder and strict aliasing rule

倖福魔咒の 提交于 2019-12-21 12:19:46
问题 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

Does inheritance via unwinding violate strict aliasing rule?

隐身守侯 提交于 2019-12-21 04:53:09
问题 I have a struct X which inherits from struct Base. However, in my current setup, due to alignment, size of X is 24B: typedef struct { double_t a; int8_t b; } Base; typedef struct { Base base; int8_t c; } X; In order to save the memory, I'd like to unwind the Base struct, so I created struct Y which contains fields from Base (in the same order, always at the beginning of the struct), so the size of the struct is 16B: typedef struct { double_t base_a; int8_t base_b; int8_t c; } Y; Then I'm