strict-aliasing

Do I understand C/C++ strict-aliasing correctly?

风流意气都作罢 提交于 2019-11-30 05:41:07
I've read this article about C/C++ strict aliasing . I think the same applies to C++. As I understand, strict aliasing is used to rearrange the code for performance optimization. That's why two pointers of different (and unrelated in C++ case) types cannot refer to the same memory location. Does this mean that problems can occur only if memory is modified? Apart of possible problems with memory alignment . For example, handling network protocol, or de-serialization. I have a byte array, dynamically allocated and packet struct is properly aligned. Can I reinterpret_cast it to my packet struct?

Does Visual C++ support “strict aliasing”?

霸气de小男生 提交于 2019-11-30 04:22:07
问题 I recently was surprised to learn that the C and C++ language standards have a "strict aliasing" rule. In essence, the rule prohibits variables of differing types from referencing the same memory location. As an example: char buffer[4] = { 0x55, 0x66, 0x77, 0x88 }; int32 *p = (int32*)&buffer[0]; // illegal because buffer[0] and *p are different types Most of the professional C++ developers I interact with are not familiar with this rule. Based on my research, it seems to affect mostly GCC/G++

Is it undefined behavior to `reinterpret_cast` a `T*` to `T(*)[N]`?

早过忘川 提交于 2019-11-30 03:01:02
Consider the following scenario: std::array<int, 8> a; auto p = reinterpret_cast<int(*)[8]>(a.data()); (*p)[0] = 42; Is this undefined behavior ? I think it is. a.data() returns a int* , which is not the same as int(*)[8] The type aliasing rules on cppreference seem to suggest that the reinterpret_cast is not valid As a programmer, I know that the memory location pointed by a.data() is an array of 8 int objects Is there any rule I am missing that makes this reinterpret_cast valid? An array object and its first element are not pointer-interconvertible * , so the result of the reinterpret_cast

How to implement fast inverse sqrt without undefined behavior? [duplicate]

﹥>﹥吖頭↗ 提交于 2019-11-30 01:47:27
问题 This question already has answers here : What's a proper way of type-punning a float to an int and vice-versa? (7 answers) Closed 2 years ago . From what I understood about strict aliasing rule, this code for fast inverse square root will result in undefined behavior in C++: float Q_rsqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long * ) &y; // type punning i = 0x5f3759df - ( i >> 1 ); y = * ( float * ) &i; y = y * (

Fix for dereferencing type-punned pointer will break strict-aliasing

旧城冷巷雨未停 提交于 2019-11-30 00:06:04
I'm trying to fix two warnings when compiling a specific program using GCC. The warnings are: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] and the two culprits are: unsigned int received_size = ntohl (*((unsigned int*)dcc->incoming_buf)); and *((unsigned int*)dcc->outgoing_buf) = htonl (dcc->file_confirm_offset); incoming_buf and outgoing_buf are defined as follows: char incoming_buf[LIBIRC_DCC_BUFFER_SIZE]; char outgoing_buf[LIBIRC_DCC_BUFFER_SIZE]; This seems subtly different than the other examples of that warning I've been examining. I

Are all pointers derived from pointers to structure types the same?

情到浓时终转凉″ 提交于 2019-11-29 23:59:19
The Question The question of whether all pointers derived from pointers to structure types are the same, is not easy to answer. I find it to be a significant question for the following two primary reasons. A. The lack of a pointer to pointer to 'any' incomplete or object type, imposes a limitation on convenient function interfaces, such as: int allocate(ANY_TYPE **p, size_t s); int main(void) { int *p; int r = allocate(&p, sizeof *p); } [ Complete code sample ] The existing pointer to 'any' incomplete or object type is explicitly described as: C99 / C11 §6.3.2.3 p1 : A pointer to void may be

Correct, portable way to interpret buffer as a struct

霸气de小男生 提交于 2019-11-29 21:00:45
The context of my problem is in network programming. Say I want to send messages over the network between two programs. For simplicity, let's say messages look like this, and byte-order is not a concern. I want to find a correct, portable, and efficient way to define these messages as C structures. I know of four approaches to this: explicit casting, casting through a union, copying, and marshaling. struct message { uint16_t logical_id; uint16_t command; }; Explicit Casting: void send_message(struct message *msg) { uint8_t *bytes = (uint8_t *) msg; /* call to write/send/sendto here */ } void

In C++, should I bother to cache variables, or let the compiler do the optimization? (Aliasing)

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-29 18:55:52
Consider the following code ( p is of type unsigned char* and bitmap->width is of some integer type, exactly which is unknown and depends on which version of some external library we're using): for (unsigned x = 0; x < static_cast<unsigned>(bitmap->width); ++x) { *p++ = 0xAA; *p++ = 0xBB; *p++ = 0xCC; } Is it worth optimizing it [..] Could there be a case where this could yield more efficient results by writing: unsigned width(static_cast<unsigned>(bitmap->width)); for (unsigned x = 0; x < width; ++x) { *p++ = 0xAA; *p++ = 0xBB; *p++ = 0xCC; } ... or is this trivial for the compiler to

Dealing with data serialization without violating the strict aliasing rule

蓝咒 提交于 2019-11-29 16:39:14
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 would like to write s to the eeprom using this function. A naive approach would be to do something like

Memcpy implementation, strict aliasing

随声附和 提交于 2019-11-29 15:38:29
问题 While learning c I have implemented my own memcpy functions. I have used a wider type( uint32_t ) in the function. (For simplicity the function is restricted to types that are multiples of 4 and the data is properly aligned ) void memcpy4( void* dst , void* src , int size ) { size /= 4; for ( int i = 0 ; i < size ; i++ ) ((uint32_t*)dst)[i] = ((uint32_t*)src)[i]; } I did some reading on type punning and strict aliasing and I believe the function above breaks the rule. The correct