Search code examples
cwindowssocketsintegerwinsock

Sending integer over socket while avoid breaking strict aliasing rule


I am attempting to send a integer over the network in C (more specifically, uint32_t bytes). I believe I am sending the data correctly, according to other examples and answers on Stack Overflow; however, when receiving the bytes, I am having trouble casting/converting them to uint32_t without breaking the strict aliasing rule. Here is an example of my inital attempt:

Sender:

uint32_t num = htonl(100);
char* converted_num = (char*)#
send(client_sock, converted_num, sizeof(num), 0);

Receiver:

char buf[8192];
recv(socket, buf, 8192, 0);
uint32_t test = ntohl(*(uint32_t*)&buf);
printf("%d\n", (int)test);

While this may appear to work, I have received feedback that the line uint32_t test = ntohl(*(uint32_t*)&buf); breaks the strict aliasing rule. Here is my attempt at fixing the strict aliasing violation:

char buf[8192];
recv(socket, buf, 8192, 0);
uint32_t test = ntohl(*(uint32_t*)memcpy(&(uint32_t){0}, &buf[0], sizeof(uint32_t)));
printf("%d\n", (int)test);

This causes the program to crash, i.e my question is how do I most efficiently avoid violating the strict aliasing rule when transferring a integer over a socket in c (windows).


Solution

  • Just break it into several lines:

    uint32_t tmp;
    memcpy(&tmp, buf + whatever, sizeof tmp);
    result = ntohl(tmp);
    

    You can make it into an inline function too:

    static inline uint32_t get_u32(char *from) {
        uint32_t tmp;
        memcpy(&tmp, from, sizeof tmp);
        return ntohl(tmp);
    }
    
    ...
    
    uint32_t test = get_u32(buf + whatever);