In a C/C++ hybrid project, I found some code that I could reduce to
#include <mem.h>
struct StructContainingDouble
{
double d;
/// other elements omitted
};
void clear(StructContainingDouble* p)
{
memset(p, 0, sizeof *p);
}
without stopping Cppcheck to raise the portability warning
Using memset() on struct which contains a floating point number.
The message is correct, but since the floating-point number is declared double, it seems to be false positive, because in double the (positive) zero value is encoded following the IEEE 754 standard:[*]
0 00000000000 0000000000000000000000000000000000000000000000000000
So I'd tend to simply suppress the warning and forget about it
void clear(ContainingDouble* p)
{
// cppcheck-suppress memsetClassFloat
memset(p, 0, sizeof *p);
}
But maybe there is really a portability issue here?
The actual code is based on the Win32 platform. The structure is used for managing access to shared memory, that's why constructors are useless. And it's not only one object of that structure that has to be zeroed, but an array of it that is embedded in another structure, something like this:
#include <mem.h>
struct Slot
{
double d;
// more members...
};
struct SharedMem
{
Slot slots[2048];
// more members...
};
void clear(SharedMem* p)
{
memset(p, 0, sizeof *p);
}
[*] from: Double-precision floating-point format - Wikipedia
It was already mentioned that C does not guarantee any particular floating point implementation.
Well, neither does C++. No specific implementation of floating point values is required.
[basic.fundamental]
There are three floating point types: float, double, and long double. [...] The value representation of floating-point types is implementation-defined.
So, memset
-ing a floating point value is not portable, in either C or C++.