cppcoreguidelines-pro-type-union-access

According to https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Ru-pun using union for type-punning is undefined behaviour.
  See also https://en.wikipedia.org/wiki/Type_punning#Use_of_union. Replace it with std::memcpy.
This commit is contained in:
wmayer
2022-06-25 17:17:04 +02:00
parent 14668197d1
commit 7de296b60e
2 changed files with 42 additions and 30 deletions

View File

@@ -321,8 +321,24 @@ void writeJPEGComment(const std::string& comment, QByteArray& ba)
const unsigned char M_EOI = 0xd9;
const unsigned char M_COM = 0xfe;
union Byte {
char c; unsigned char u;
class Byte {
char c{};
unsigned char u{};
public:
void setc(char v) {
c = v;
std::memcpy(&u, &c, sizeof(u));
}
void setu(unsigned char v) {
u = v;
std::memcpy(&c, &u, sizeof(c));
}
char getc() const {
return c;
}
unsigned char getu() const {
return u;
}
};
if (comment.empty() || ba.length() < 2)
@@ -330,21 +346,21 @@ void writeJPEGComment(const std::string& comment, QByteArray& ba)
// first marker
Byte a,b;
a.c = ba[0];
b.c = ba[1];
if (a.u == 0xff && b.u == M_SOI) {
a.setc(ba[0]);
b.setc(ba[1]);
if (a.getu() == 0xff && b.getu() == M_SOI) {
int index = 2;
int len = ba.length();
while (index < len) {
// next marker
a.c = ba[index++];
while (a.u != 0xff && index < len) {
a.c = ba[index++];
a.setc(ba[index++]);
while (a.getu() != 0xff && index < len) {
a.setc(ba[index++]);
}
do {
b.c = ba[index++];
} while (b.u == 0xff && index < len);
switch (b.u) {
b.setc(ba[index++]);
} while (b.getu() == 0xff && index < len);
switch (b.getu()) {
case M_SOF0:
case M_SOF1:
case M_SOF2:
@@ -361,11 +377,11 @@ void writeJPEGComment(const std::string& comment, QByteArray& ba)
case M_EOI:
{
Byte a, b;
a.u = 0xff;
b.u = M_COM;
a.setu(0xff);
b.setu(M_COM);
index -= 2; // insert comment before marker
ba.insert(index++, a.c);
ba.insert(index++, b.c);
ba.insert(index++, a.getc());
ba.insert(index++, b.getc());
int val = comment.size() + 2;
ba.insert(index++,(val >> 8) & 0xff);
ba.insert(index++,val & 0xff);
@@ -376,9 +392,9 @@ void writeJPEGComment(const std::string& comment, QByteArray& ba)
default:
{
Byte a, b;
a.c = ba[index++];
b.c = ba[index++];
int off = ((unsigned int)a.u << 8) + (unsigned int)b.u;
a.setc(ba[index++]);
b.setc(ba[index++]);
int off = ((unsigned int)a.getu() << 8) + (unsigned int)b.getu();
index += off;
index -= 2; // next marker
} break;
@@ -464,7 +480,7 @@ SoQtOffscreenRenderer::setViewportRegion(const SbViewportRegion & region)
Returns the viewerport region.
*/
const SbViewportRegion &
SoQtOffscreenRenderer::getViewportRegion(void) const
SoQtOffscreenRenderer::getViewportRegion() const
{
return PRIVATE(this)->viewport;
}
@@ -486,7 +502,7 @@ SoQtOffscreenRenderer::setBackgroundColor(const SbColor4f & color)
Returns the background color.
*/
const SbColor4f &
SoQtOffscreenRenderer::getBackgroundColor(void) const
SoQtOffscreenRenderer::getBackgroundColor() const
{
return PRIVATE(this)->backgroundcolor;
}
@@ -510,7 +526,7 @@ SoQtOffscreenRenderer::setGLRenderAction(SoGLRenderAction * action)
Returns the rendering action currently used.
*/
SoGLRenderAction *
SoQtOffscreenRenderer::getGLRenderAction(void) const
SoQtOffscreenRenderer::getGLRenderAction() const
{
return PRIVATE(this)->renderaction;
}
@@ -522,7 +538,7 @@ SoQtOffscreenRenderer::setNumPasses(const int num)
}
int
SoQtOffscreenRenderer::getNumPasses(void) const
SoQtOffscreenRenderer::getNumPasses() const
{
return PRIVATE(this)->numSamples;
}

View File

@@ -1097,15 +1097,11 @@ void PcdReader::read(const std::string& filename)
}
}
else if (types[rgba] == "F") {
union RGBA {
uint32_t u;
float f;
};
union RGBA v;
static_assert(sizeof(float) == sizeof(uint32_t), "float and uint32_t have different sizes");
for (std::size_t i=0; i<numPoints; i++) {
v.f = static_cast<float>(data(i,rgba));
uint32_t packed = v.u;
float f = static_cast<float>(data(i,rgba));
uint32_t packed;
std::memcpy(&packed, &f, sizeof(packed));
uint32_t a = (packed >> 24) & 0xff;
uint32_t r = (packed >> 16) & 0xff;
uint32_t g = (packed >> 8) & 0xff;