I'm running CppCheck on some legacy and trying to fix all reported issues. I've got some portability warnings related to casting that I can't find how to fix.
I isolated the code in a MVCE, basically, we receive a char*
(read from a USB driver). This array represents double
values. To interpret them, we use a cast from char*
to double*
, it works well for all our supported platforms, but CppCheck does not like that.
Is there a better C++ way to to this? Or should I simply silent the warning for those lines?
void printAsDouble( char* myData, size_t size )
{
if ( size%sizeof(double) == 0 )
{
double* array = (double*)myData;
for (size_t pos = 0; pos != size/sizeof(double); ++pos)
std::cout << "Value #" << (pos+1) << " is " << array[pos] << std::endl;
}
}
CppCheck reports portability: Casting between char * and double * which have an incompatible binary data representation.
cppcheck is right to flag this code, but not for that reason. Casting from char *
to double *
is only safe if the char pointer is aligned for double
. Otherwise you have undefined behaviour when you attempt to perform an unaligned load from the casted pointer.
You can use memcpy instead to load the data as doubles:
double value;
memcpy(&value, myData + pos, sizeof(double));
…
pos += sizeof(double);
Most compilers will optimize the memcpy into an appropriate load (or multiple loads) depending on your CPU's support for unaligned loads.