0

I'm using boost::uuids inside maps (labeled_graph, actually), so I need a properly working operator <. Unfortunately it isn't, if BOOST_UUID_USE_SSE2 is enabled (and thus, uuid_x86.hpp is used).

Here is example code:

#include <boost/uuid/nil_generator.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <string>
#include <sstream>
#include <iostream>

#include <assert.h>

#define CHECK(x)  do { if(x) { std::cout << #x << "\n"; } } while(0)

static inline boost::uuids::uuid StringToUuid(const std::string &str)
{
    boost::uuids::uuid u = boost::uuids::nil_uuid();
    std::stringstream uuidstring(str);
    uuidstring >> u;
    return u;
}

int main() {
    boost::uuids::uuid vmi_uuid = StringToUuid("00000000-0000-0000-0000-000000000001");
    boost::uuids::uuid vmi2_uuid = StringToUuid("00000000-0000-0000-0000-000000000002");

    CHECK(vmi_uuid != vmi2_uuid);
    CHECK(vmi_uuid < vmi2_uuid);
    CHECK(vmi2_uuid < vmi_uuid);

    return 0;
}

When uuid_x86.hpp is used, operator< is incosistent -- returns false in both cases:

vmi_uuid != vmi2_uuid

Disabling intrinsic-based header returns things back to normal:

vmi_uuid != vmi2_uuid
vmi_uuid < vmi2_uuid

This is reproducable only with special UUIDs (1 and 2), having totally random ids doesn't reveal this problem.

I have Ubuntu Xenial with libboost 1.58. CPU is i7-6600U if it matters. Am I missing something?

myaut
  • 11,174
  • 2
  • 30
  • 62
  • Comparing an UUID for equality or inequality makes sense, but not really any relational comparisons. What does it mean for an UUID to be "less" (or "greater") than another? – Some programmer dude Aug 28 '19 at 12:20
  • It is only needed for building ordered containers such as `std::map` (unfortunately, unordered_map is unavailable for me). – myaut Aug 28 '19 at 12:23
  • 1
    Unfortunately UUID ordering is meaningless. Take two UUID's from somewhere (not artificially constructed like yours). Does it make sense to call one "smaller" than the other? No it doesn't. If you need a dictionary-like container but have no access to C++11 `std::unordered_map` then use e.g. [Boost `unordered_map`](https://www.boost.org/doc/libs/1_71_0/doc/html/boost/unordered_map.html) (or any of the million of hash-table implementations available). – Some programmer dude Aug 28 '19 at 12:28
  • Works as expected for me with gcc 8.3 on Ubuntu Disco. Did you inspect the actual values in UUIDs? The compiler may be able to (incorrectly) fill the UUIDs in compile time. You can try moving the strings to a separate translation unit to mitigate that. Did you try different compilers and compiler optimization options? – Andrey Semashev Aug 28 '19 at 17:59

0 Answers0