strict-aliasing

How to cast sockaddr_storage and avoid breaking strict-aliasing rules

柔情痞子 提交于 2019-11-28 16:53:03
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 sockaddr_storage their_addr; ... inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr)

C memory allocator and strict aliasing

送分小仙女□ 提交于 2019-11-28 09:22:24
even after reading quite a bit about the strict-aliasing rules I am still confused. As far as I have understood this, it is impossible to implement a sane memory allocator that follows these rules, because malloc can never reuse freed memory, as the memory could be used to store different types at each allocation. Clearly this cannot be right. What am I missing? How do you implement an allocator (or a memory pool) that follows strict-aliasing? Thanks. Edit: Let me clarify my question with a stupid simple example: // s == 0 frees the pool void *my_custom_allocator(size_t s) { static void *pool

Undefined behavior on reading object using non-character type when last written using character type

淺唱寂寞╮ 提交于 2019-11-28 08:17:05
Assuming unsigned int has no trap representations, do either or both of the statements marked (A) and (B) below provoke undefined behavior, why or why not, and (especially if you think one of them is well-defined but the other isn't), do you consider that a defect in the standard? I am primarily interested in the current version of the C standard (i.e. C2011), but if this is different in older versions of the standard, or in C++, I would also like to know about that. ( _Alignas is used in this program to eliminate any question of UB due to inadequate alignment. The rules I discuss in my

Has a std::byte pointer the same aliasing implications as char*?

北慕城南 提交于 2019-11-28 08:08:58
C++ (and C) strict aliasing rules include that a char* and unsigned char* may alias any other pointer. AFAIK there is no analogous rule for uint8_t* . Thus my question: What are the aliasing rules for a std::byte pointer? The C++ reference currently just specifies : Like the character types (char, unsigned char, signed char) it can be used to access raw memory occupied by other objects (object representation), but unlike those types, it is not a character type and is not an arithmetic type. DeiDei From the current Standard draft ([basic.types]/2): For any object (other than a base-class

Using this pointer causes strange deoptimization in hot loop

梦想与她 提交于 2019-11-28 03:31:07
I recently came across a strange deoptimization (or rather missed optimization opportunity). Consider this function for efficient unpacking of arrays of 3-bit integers to 8-bit integers. It unpacks 16 ints in each loop iteration: void unpack3bit(uint8_t* target, char* source, int size) { while(size > 0){ uint64_t t = *reinterpret_cast<uint64_t*>(source); target[0] = t & 0x7; target[1] = (t >> 3) & 0x7; target[2] = (t >> 6) & 0x7; target[3] = (t >> 9) & 0x7; target[4] = (t >> 12) & 0x7; target[5] = (t >> 15) & 0x7; target[6] = (t >> 18) & 0x7; target[7] = (t >> 21) & 0x7; target[8] = (t >> 24)

Shared memory buffers in C++ without violating strict aliasing rules

耗尽温柔 提交于 2019-11-28 00:30:08
问题 I am struggling with implementing a shared memory buffer without breaking C99's strict aliasing rules. Suppose I have some code that processes some data and needs to have some 'scratch' memory to operate. I could write it as something like: void foo(... some arguments here ...) { int* scratchMem = new int[1000]; // Allocate. // Do stuff... delete[] scratchMem; // Free. } Then I have another function that does some other stuff that also needs a scratch buffer: void bar(...arguments...) { float

How to cast the address of a pointer generically while conforming to the C standard

时光毁灭记忆、已成空白 提交于 2019-11-28 00:08:11
问题 It is common to assign pointers with allocations using an implicit function-return void * conversion, just like malloc()'s: void *malloc(size_t size); int *pi = malloc(sizeof *pi); I would like to perform the same assignment while passing the address of the target pointer, and without explicitly casting its type from within the function (not within its body, nor arguments). The following code seems to achieve just that. I would like to know whether the code fully conforms with (any of) the C

C aliasing rules and memcpy

寵の児 提交于 2019-11-27 21:43:38
问题 While answering another question, I thought of the following example: void *p; unsigned x = 17; assert(sizeof(void*) >= sizeof(unsigned)); *(unsigned*)&p = 17; // (1) memcpy(&p, &x, sizeof(x)); // (2) Line 1 breaks aliasing rules. Line 2, however, is OK wrt. aliasing rules. The question is: why? Does the compiler have special built-in knowledge about functions such as memcpy, or are there some other rules that make memcpy OK? Is there a way of implementing memcpy-like functions in standard C

When is char* safe for strict pointer aliasing?

怎甘沉沦 提交于 2019-11-27 21:11:24
I've been trying to understand the strict aliasing rules as they apply to the char pointer. Here this is stated: It is always presumed that a char* may refer to an alias of any object. Ok so in the context of socket code, I can do this: struct SocketMsg { int a; int b; }; int main(int argc, char** argv) { // Some code... SocketMsg msgToSend; msgToSend.a = 0; msgToSend.b = 1; send(socket, (char*)(&msgToSend), sizeof(msgToSend); }; But then there's this statement The converse is not true. Casting a char* to a pointer of any type other than a char* and dereferencing it is usually in violation of

strict aliasing and alignment

偶尔善良 提交于 2019-11-27 18:50:28
I need a safe way to alias between arbitrary POD types, conforming to ISO-C++11 explicitly considering 3.10/10 and 3.11 of n3242 or later. There are a lot of questions about strict aliasing here, most of them regarding C and not C++. I found a "solution" for C which uses unions, probably using this section union type that includes one of the aforementioned types among its elements or nonstatic data members From that I built this. #include <iostream> template <typename T, typename U> T& access_as(U* p) { union dummy_union { U dummy; T destination; }; dummy_union* u = (dummy_union*)p; return u-