What's the difference between gcc and clang unordered_map::insert() implementation?

Viewed 92

The code below produced different result under gcc and clang. For gcc, X has been copied 10 times, but for clang, it's copied only once, why?

It seems as if different unordered_map::insert() overload had been chosen for gcc and clang. Has the STL standard defined the behavior of this kind of insertion?

#include <iostream>
#include <unordered_map>

struct X {
  X() {
    std::cout << "construct" << std::endl;
  }
  X(const X& x) {
    std::cout << "copied" << std::endl;
  }
  bool operator==(const X& x) const{
    return true;
  }
};

namespace std {
   template<>
   struct hash<X> {
     std::size_t operator()(const X&x ) const {
       return 0;
     }
   };
}


int main(){
  std::pair<const X, int> e{};
  std::unordered_map<X, int> m;
  for( int i = 0 ; i<10;i++) {
    m.insert(e);
  }
  return 0;
}
gcc version 8.3.1 20190604
$g++ test.cc -std=c++17 && ./a.out
construct
copied
copied
copied
copied
copied
copied
copied
copied
copied
copied
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
$clang++ test.cc -std=c++17 && ./a.out
construct
copied // printed only once

And if I make e a const, the output will be same for both gcc and clang:

const std::pair<const X, int> e{};
0 Answers
Related