strict-aliasing

GCC: accuracy of strict aliasing warnings

為{幸葍}努か 提交于 2019-11-27 17:21:08
问题 I'm trying to check some of my code for strict aliasing violations, but it looks like I've missed something while trying to understand the strict aliasing rule. Imagine the following code: #include <stdio.h> int main( void ) { unsigned long l; l = 0; *( ( unsigned short * )&l ) = 1; printf( "%lu\n", l ); return 0; } Classic and basic example. With GCC 4.9 ( -Wall -fstrict-aliasing -Wstrict-aliasing -O3 ), it actually reports the error: dereferencing type-punned pointer will break strict

Is the strict aliasing rule really a “two-way street”?

*爱你&永不变心* 提交于 2019-11-27 16:09:20
问题 In these comments user @Deduplicator insists that the strict aliasing rule permits access through an incompatible type if either of the aliased or the aliasing pointer is a pointer-to-character type (qualified or unqualified, signed or unsigned char * ). So, his assertion is basically that both long long foo; char *p = (char *)&foo; *p; // just in order to dereference 'p' and char foo[sizeof(long long)]; long long *p = (long long *)&foo[0]; *p; // just in order to dereference 'p' are

Is unsigned char a[4][5]; a[1][7]; undefined behavior?

淺唱寂寞╮ 提交于 2019-11-27 15:02:56
问题 One of the examples of undefined behavior from the C standard reads (J.2): — An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6) If the declaration is changed from int a[4][5] to unsigned char a[4][5] , does accessing a[1][7] still result in undefined behavior? My opinion is that it does not, but I have heard from others who disagree, and I'd like to see what

How to implement “_mm_storeu_epi64” without aliasing problems?

*爱你&永不变心* 提交于 2019-11-27 14:21:42
(Note: Although this question is about "store", the "load" case has the same issues and is perfectly symmetric.) The SSE intrinsics provide an _mm_storeu_pd function with the following signature: void _mm_storeu_pd (double *p, __m128d a); So if I have vector of two doubles, and I want to store it to an array of two doubles, I can just use this intrinsic. However, my vector is not two doubles; it is two 64-bit integers, and I want to store it to an array of two 64-bit integers. That is, I want a function with the following signature: void _mm_storeu_epi64 (int64_t *p, __m128i a); But the

What is the effective type of an object written by memset?

落花浮王杯 提交于 2019-11-27 12:24:47
Code 1: unsigned int *p = malloc(sizeof *p); memset(p, 0x55, sizeof *p); unsigned int u = *p; Code 2: void *d = malloc(50); *(double *)d = 1.23; memset(d, 0x55, 50); unsigned int u = *(unsigned int *)d; In each case, what effect does memset have on the effective type of the object in the malloc'd space; and so is initializing u correct or a strict aliasing violation? The definition of effective type (C11 6.5/6) is: The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an

Dereferencing type-punned pointer will break strict-aliasing rules

放肆的年华 提交于 2019-11-27 11:06:47
I used the following piece of code to read data from files as part of a larger program. double data_read(FILE *stream,int code) { char data[8]; switch(code) { case 0x08: return (unsigned char)fgetc(stream); case 0x09: return (signed char)fgetc(stream); case 0x0b: data[1] = fgetc(stream); data[0] = fgetc(stream); return *(short*)data; case 0x0c: for(int i=3;i>=0;i--) data[i] = fgetc(stream); return *(int*)data; case 0x0d: for(int i=3;i>=0;i--) data[i] = fgetc(stream); return *(float*)data; case 0x0e: for(int i=7;i>=0;i--) data[i] = fgetc(stream); return *(double*)data; } die("data read failed")

How to cast sockaddr_storage and avoid breaking strict-aliasing rules

不打扰是莪最后的温柔 提交于 2019-11-27 10:01:58
问题 I'm using Beej's Guide to Networking and came across an aliasing issue. He proposes a function to return either the IPv4 or IPv6 address of a particular struct: 1 void *get_in_addr( struct sockaddr *sa ) 2 { 3 if (sa->sa_family == AF_INET) 4 return &(((struct sockaddr_in*)sa)->sin_addr); 5 else 6 return &(((struct sockaddr_in6*)sa)->sin6_addr); 7 } This causes GCC to spit out a strict-aliasing error for sa on line 3. As I understand it, it is because I call this function like so: struct

union for uint32_t and uint8_t[4] undefined behavior? [duplicate]

耗尽温柔 提交于 2019-11-27 09:09:42
This question already has an answer here: Purpose of Unions in C and C++ 15 answers In the comments of this answer it is said that it would be undefined behavior to split up an integer into their bytes using a union like follows. The code given at that place is similar though not identical to this, please give a note if have I changed undefined-behavior-relevant aspects of the code. union addr { uint8_t addr8[4]; uint32_t addr32; }; Up to now I thought this would be a fine approach to do things like addr = {127, 0, 0, 1}; and get the corresponding uint32_t in return. (I acknowledge that this

Does accessing the first field of a struct via a C cast violate strict aliasing?

时光毁灭记忆、已成空白 提交于 2019-11-27 08:54:16
Does this code violate strict aliasing? struct {int x;} a; *(int*)&a = 3 More abstractly, is it legal to cast between different types as long as the primitive read/write operations are type correct? First, it is legal to cast in C. §6.7.2.1/13: Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be

float bits and strict aliasing

安稳与你 提交于 2019-11-27 07:50:56
I am trying to extract the bits from a float without invoking undefined behavior. Here is my first attempt: unsigned foo(float x) { unsigned* u = (unsigned*)&x; return *u; } As I understand it, this is not guaranteed to work due to strict aliasing rules, right? Does it work if a take an intermediate step with a character pointer? unsigned bar(float x) { char* c = (char*)&x; unsigned* u = (unsigned*)c; return *u; } Or do I have to extract the individual bytes myself? unsigned baz(float x) { unsigned char* c = (unsigned char*)&x; return c[0] | c[1] << 8 | c[2] << 16 | c[3] << 24; } Of course