user2717575
user2717575

Reputation: 409

dereferencing type-punned pointer will break strict-aliasing rules: array of bytes to a number

I have already read a number of questions about this warning (Dereferencing type-punned pointer will break strict-aliasing rules, Dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing], What is the strict aliasing rule?, "dereferencing type-punned pointer will break strict-aliasing rules" warning and others) and got totally confused about my warning.

So I have a struct:

typedef struct {
    unsigned char precision;
    unsigned char scale;
    unsigned char array[33];
} DBNUMERIC;

This struct is filled by FreeTDS library when retrieving data from MS SQL Server. I know that starting from array[1] there is 64-bit integral number (in big-endian) and I want to get it. I use the following code:

int64_t result = 0;
result = be64toh(*((decltype(result)*)(numeric.array + 1)));

But GCC gives me the warning dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]. But if I use the code:

int64_t result = 0;
decltype(result)* temp_ptr = (decltype(result)*)(numeric.array + 1);
decltype(result) temp = *temp_ptr;
result = be64toh(temp);

there are no warnings about violating strict-aliasing rules. I don't think that this code differs from the original, therefore I am confused. How can I convert 8 bytes from the array to a int64_t variable?

Upvotes: 3

Views: 938

Answers (1)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158469

Both of your cases violate the strict aliasing rules. gcc's strict-aliasing warnings are subject to false negatives and false positives depending on the warning and optimization levels.

If you want to type-pun in a way not allowed by the strict aliasing rules then you should just use std::memcpy:

std::memcpy(&result, numeric.array+1, sizeof(int64_t ));

We can see from the following sources; this article Type Punning, Strict Aliasing, and Optimization and the std-dicussion conversation on type punning and unions I quote in my answer here tell us that the compiler should be smart enough to optimize for the use of memcpy to generate efficient code.

Upvotes: 5

Related Questions