type-punning

Aliasing through unions

偶尔善良 提交于 2021-01-27 14:16:51
问题 The 6.5(p7) has a bullet about union s and aggregate s: An object shall have its stored value accessed only by an lvalue expression that has one of the following types: [...] — an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or This is not quite clear what it means. Does it require at least one member or all members to satisfy the strict aliasing rule. Particularly about union s

Why is type punning considered UB?

可紊 提交于 2021-01-04 03:16:05
问题 Imagine this: uint64_t x = *(uint64_t *)((unsigned char[8]){'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}); I have read that type puns like that are undefined behavior. Why? I am literally, reinterpreting 8 bytes of bytes into an 8 byte integer. I don't see how that's different from a union except the type pun being undefined behavior and union s not being? I asked a fellow programmer in person and they said that if you're doing it, either you know what you're doing very well , or you're making a

Why is type punning considered UB?

穿精又带淫゛_ 提交于 2021-01-04 03:14:25
问题 Imagine this: uint64_t x = *(uint64_t *)((unsigned char[8]){'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}); I have read that type puns like that are undefined behavior. Why? I am literally, reinterpreting 8 bytes of bytes into an 8 byte integer. I don't see how that's different from a union except the type pun being undefined behavior and union s not being? I asked a fellow programmer in person and they said that if you're doing it, either you know what you're doing very well , or you're making a

Why is type punning considered UB?

别等时光非礼了梦想. 提交于 2021-01-04 03:13:25
问题 Imagine this: uint64_t x = *(uint64_t *)((unsigned char[8]){'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}); I have read that type puns like that are undefined behavior. Why? I am literally, reinterpreting 8 bytes of bytes into an 8 byte integer. I don't see how that's different from a union except the type pun being undefined behavior and union s not being? I asked a fellow programmer in person and they said that if you're doing it, either you know what you're doing very well , or you're making a

Is reinterpret_cast<char*>(myTypePtr) assumed to point to an array?

牧云@^-^@ 提交于 2020-07-08 01:12:46
问题 We know that char* can alias anything: According to cppreference Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true: [...] AliasedType is std::byte , char , or unsigned char : this permits examination of the object representation of any object as an array of bytes . [...] The statement in boldface is not present in n4659 draft [6.10, (8.8)]. Since

Is reinterpret_cast<char*>(myTypePtr) assumed to point to an array?

喜夏-厌秋 提交于 2020-07-08 01:12:00
问题 We know that char* can alias anything: According to cppreference Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true: [...] AliasedType is std::byte , char , or unsigned char : this permits examination of the object representation of any object as an array of bytes . [...] The statement in boldface is not present in n4659 draft [6.10, (8.8)]. Since

Is reinterpret_cast type punning actually undefined behavior?

北城以北 提交于 2020-06-10 04:38:10
问题 It appears to be widely-held that type punning via reinterpret_cast is somehow prohibited (properly: "undefined behavior", that is, "behavior for which this International Standard imposes no requirements", with an explicit note that implementations may define behavior) in C++. Am I incorrect in using the following reasoning to disagree, and if so, why ? [expr.reinterpret.cast]/11 states: A glvalue expression of type T1 can be cast to the type “reference to T2 ” if an expression of type

Is it possible to write Quake's fast InvSqrt() function in Rust?

爱⌒轻易说出口 提交于 2020-04-07 10:52:06
问题 This is just to satisfy my own curiosity. Is there an implementation of this: float InvSqrt (float x) { float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i>>1); x = *(float*)&i; x = x*(1.5f - xhalf*x*x); return x; } in Rust? If it exists, post the code. I tried it and failed. I don't know how to encode the float number using integer format. Here is my attempt: fn main() { println!("Hello, world!"); println!("sqrt1: {}, ",sqrt2(100f64)); } fn sqrt1(x: f64) -> f64 { x.sqrt() } fn sqrt2

Reliable type-punning across C and C++ standards

冷暖自知 提交于 2020-01-23 06:17:29
问题 Is there a way to type-pun that is valid in both C and C++? Preferably low overhead, and avoiding trivial preprocessor hacks. In C89, I know I can do something like this: unsigned int float_bits(float num) { return *(unsigned int *)&num; } However this violates C99's strict aliasing rule. So something like this might be more portable across the various C standards: unsigned int float_bits(float num) { union { float f; unsigned int i; } u; u.f = num; return u.i; } But I know that this is not