Fixes Undefined Behavior in LaneTupel (Strict Aliasing), resolves 2665

It's complicated :sigh: read this please:
http://dbp-consulting.com/tutorials/StrictAliasing.html

tl;dr: has to go through a memcpy (in C++) as in:
184cc11cee/src/support/utilities.h (L29-L40)
This commit is contained in:
Daniel J. Hofmann 2016-07-18 12:32:25 +02:00
parent 50cbba1620
commit 130d5298fc

View File

@ -2,6 +2,7 @@
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <tuple>
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -24,10 +25,8 @@ LaneTupel::LaneTupel(const LaneID lanes_in_turn, const LaneID first_lane_from_th
// comparation based on interpretation as unsigned 32bit integer // comparation based on interpretation as unsigned 32bit integer
bool LaneTupel::operator==(const LaneTupel other) const bool LaneTupel::operator==(const LaneTupel other) const
{ {
static_assert(sizeof(LaneTupel) == sizeof(std::uint16_t), return std::tie(lanes_in_turn, first_lane_from_the_right) ==
"Comparation requires LaneTupel to be the of size 16Bit"); std::tie(other.lanes_in_turn, other.first_lane_from_the_right);
return *reinterpret_cast<const std::uint16_t *>(this) ==
*reinterpret_cast<const std::uint16_t *>(&other);
} }
bool LaneTupel::operator!=(const LaneTupel other) const { return !(*this == other); } bool LaneTupel::operator!=(const LaneTupel other) const { return !(*this == other); }
@ -35,10 +34,8 @@ bool LaneTupel::operator!=(const LaneTupel other) const { return !(*this == othe
// comparation based on interpretation as unsigned 32bit integer // comparation based on interpretation as unsigned 32bit integer
bool LaneTupel::operator<(const LaneTupel other) const bool LaneTupel::operator<(const LaneTupel other) const
{ {
static_assert(sizeof(LaneTupel) == sizeof(std::uint16_t), return std::tie(lanes_in_turn, first_lane_from_the_right) <
"Comparation requires LaneTupel to be the of size 16Bit"); std::tie(other.lanes_in_turn, other.first_lane_from_the_right);
return *reinterpret_cast<const std::uint16_t *>(this) <
*reinterpret_cast<const std::uint16_t *>(&other);
} }
} // namespace guidance } // namespace guidance