strict-aliasing

Is this use of unions strictly conforming?

假如想象 提交于 2019-12-02 22:35:58
Given the code: struct s1 {unsigned short x;}; struct s2 {unsigned short x;}; union s1s2 { struct s1 v1; struct s2 v2; }; static int read_s1x(struct s1 *p) { return p->x; } static void write_s2x(struct s2 *p, int v) { p->x=v;} int test(union s1s2 *p1, union s1s2 *p2, union s1s2 *p3) { if (read_s1x(&p1->v1)) { unsigned short temp; temp = p3->v1.x; p3->v2.x = temp; write_s2x(&p2->v2,1234); temp = p3->v2.x; p3->v1.x = temp; } return read_s1x(&p1->v1); } int test2(int x) { union s1s2 q[2]; q->v1.x = 4321; return test(q,q+x,q+x); } #include <stdio.h> int main(void) { printf("%d\n",test2(0)); }

Reusing a float buffer for doubles without undefined behaviour

前提是你 提交于 2019-12-02 22:06:50
In one particular C++ function, I happen to have a pointer to a big buffer of floats that I want to temporarily use to store half the number of doubles. Is there a method to use this buffer as scratch space for storing the doubles, which is also allowed (i.e., not undefined behaviour) by the standard? In summary, I would like this: void f(float* buffer) { double* d = reinterpret_cast<double*>(buffer); // make use of d d[i] = 1.; // done using d as scratch, start filling the buffer buffer[j] = 1.; } As far as I see there's no easy way to do this: if I understand correctly, a reinterpret_cast

Is using the result of new char[] or malloc to casted float * is UB (strict aliasing violation)?

狂风中的少年 提交于 2019-12-02 19:28:57
Which code of these has UB (specifically, which violates strict aliasing rule)? void a() { std::vector<char> v(sizeof(float)); float *f = reinterpret_cast<float *>(v.data()); *f = 42; } void b() { char *a = new char[sizeof(float)]; float *f = reinterpret_cast<float *>(a); *f = 42; } void c() { char *a = new char[sizeof(float)]; float *f = new(a) float; *f = 42; } void d() { char *a = (char*)malloc(sizeof(float)); float *f = reinterpret_cast<float *>(a); *f = 42; } void e() { char *a = (char*)operator new(sizeof(float)); float *f = reinterpret_cast<float *>(a); *f = 42; } I ask this, because of

Violating of strict-aliasing in C, even without any casting?

旧巷老猫 提交于 2019-12-02 17:50:30
How can *i and u.i print different numbers in this code, even though i is defined as int *i = &u.i; ? I can only assuming that I'm triggering UB here, but I can't see how exactly. ( ideone demo replicates if I select 'C' as the language. But as @2501 pointed out, not if 'C99 strict' is the language. But then again, I get the problem with gcc-5.3.0 -std=c99 !) // gcc -fstrict-aliasing -std=c99 -O2 union { int i; short s; } u; int * i = &u.i; short * s = &u.s; int main() { *i = 2; *s = 100; printf(" *i = %d\n", *i); // prints 2 printf("u.i = %d\n", u.i); // prints 100 return 0; } (gcc 5.3.0,

Is std::memcpy between different trivially copyable types undefined behavior?

南楼画角 提交于 2019-12-02 17:23:38
I've been using std::memcpy to circumvent strict aliasing for a long time. For example, inspecting a float , like this : float f = ...; uint32_t i; static_assert(sizeof(f)==sizeof(i)); std::memcpy(&i, &f, sizeof(i)); // use i to extract f's sign, exponent & significand However, this time, I've checked the standard, I haven't found anything that validates this. All I found is this : For any object (other than a potentially-overlapping subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes ([intro.memory]) making up the object can

Is placement new legally required for putting an int into a char array?

一世执手 提交于 2019-12-02 17:15:28
There seems to be some agreement that you can't willy nilly point (an int*) into a char array because of the C++ aliasing rules. From this other question -- Generic char[] based storage and avoiding strict-aliasing related UB -- it seems that it is allowed to (re-)use storage through placement new. alignas(int) char buf[sizeof(int)]; void f() { // turn the memory into an int: (??) from the POV of the abstract machine! ::new (buf) int; // is this strictly required? (aside: it's obviously a no-op) // access storage: *((int*)buf) = 42; // for this discussion, just assume the cast itself yields

Dealing with data serialization without violating the strict aliasing rule

旧巷老猫 提交于 2019-12-02 12:57:58
问题 Often in embedded programming (but not limited to) there is a need to serialize some arbitrary struct in order to send it over some communication channel or write to some memory. Example Let's consider a structure composed of different data types in a N -aligned memory region: struct { float a; uint8_t b; uint32_t c; } s; Now let's assume we have a library function void write_to_eeprom(uint32_t *data, uint32_t len); which is taking the pointer to data to be written as a uint32_t* . Now we

Does this union break strict aliasing? What about floating point registers

我是研究僧i 提交于 2019-12-02 02:26:14
问题 union { Uint32 Integer; Float32 Real; } Field; I have to use that union for a little IEEE trick, does that break strict aliasing? GCC is not throwing any warning(tried with GCC 4.5 and 4.6 even with pedantic strict aliasing, but As Far As I Know, GCC is not very good catching strict aliasing rules infringiments (lots of false positives/negatives). Field A; A.Integer = (Value1 & B) || Value2; return A.Real; That's the snippet I'm currently using, it seems working correctly without any warning,

Strict aliasing rule

徘徊边缘 提交于 2019-12-01 18:36:29
问题 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

malloc-free-malloc and strict-aliasing

我的未来我决定 提交于 2019-12-01 18:03:24
问题 I've been trying to understand a particular aspect of strict aliasing recently, and I think I have made the smallest possible interesting piece of code. (Interesting for me, that is!) Update: Based on the answers so far, it's clear I need to clarify the question. The first listing here is "obviously" defined behaviour, from a certain point of view. The real issue is to follow this logic through to custom allocators and custom memory pools. If I malloc a large block of memory at the start, and