5

When moving an unordered_set out on GCC 4.9, and then reusing the moved-from object, I am getting a divide-by-zero when I add to it.

My understanding (from http://en.cppreference.com/w/cpp/utility/move) is that the moved-from object can be used provided none of its preconditions are violated. Calling clear() on the moved-from set is fine (which makes sense in the context of preconditions), but it's not clear to me that I'm violating any precondition by adding a new element.

Example code:

#include <unordered_set>
using namespace std;
void foo(unordered_set<int> &&a) {
  unordered_set<int> copy = std::move(a);
}

void test() {
  unordered_set<int> a;
  for (int i = 0; i < 12; ++i) a.insert(i);
  foo(std::move(a));

  a.clear();
  a.insert(34); // divide by zero here
}

int main() {
  test();
}​

This code works fine on GCC4.7 - is this an issue in GCC4.9's unordered_set implementation, or in my understanding of what it means to violate preconditions on moved-from objects?

manlio
  • 18,345
  • 14
  • 76
  • 126
Matt Godbolt
  • 1,381
  • 11
  • 14
  • 1
    gcc 4.7 is not a C++11 compliant implementation, you maybe want to reconsider your assumptions . – user2485710 May 22 '14 at 21:42
  • 1
    Known bug in 4.9, already fixed. – Marc Glisse May 22 '14 at 21:43
  • 1
    @MarcGlisse link to the bugzilla ? – user2485710 May 22 '14 at 21:43
  • 4
    I think it's https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61143 (even though at first glance it *appears* not to be) –  May 22 '14 at 21:45
  • @user2485710 So does that mean we're not allowed to talk about any gcc version prior one where they announce complete C++11 compliance? Unless you have specific knowledge that `unordered_set` wasn't implemented fully in gcc4.7 maybe you want to reconsider posting nonsense comments. – Praetorian May 22 '14 at 21:50
  • @Praetorian: I believe he's saying that you can't assume that Gcc 4.7 is C++11 compliant. He's not even claiming it's not compliant, only that it's not safe to assume it is. Makes sense to me – Mooing Duck May 22 '14 at 21:55
  • @MooingDuck But there is no issue of full C++11 compliance here! The only thing that matters is whether the `unordered_set` implementation that shipped with gcc4.7 was *intended* to be compliant. user's comment is tangential to the problem at hand, and generally unhelpful in any context other than if you were complaining about as yet unimplemented features in gcc – Praetorian May 22 '14 at 21:59
  • 1
    @Praetorian I don't think that there is any such thing as _intended to be compliant_ . If you want to use any random release of `gcc` go for it, but I like to follow the path traced by the developers of the software that I'm using, not trying new roads just for the sake of it. – user2485710 May 22 '14 at 22:02
  • @user2485710 Good for you. I said *intended to be compliant* because, as evident, there may be bugs in the implementation. Anyway, I'm not continuing this debate, you win. – Praetorian May 22 '14 at 22:04

2 Answers2

9

This is PR 61143. It has been fixed for gcc-4.10 and the fix has been backported in time for 4.9.1.

Marc Glisse
  • 7,550
  • 2
  • 30
  • 53
3

Marc Glisse has already referred you to the GCC bug, but to answer your question:

is this an issue ... in my understanding of what it means to violate preconditions on moved-from objects?

No, it isn't, your understanding is correct. Making the code in your question work isn't just a GCC extension, your program is perfectly valid. A moved-from object of a type defined in the standard library is supposed to remain usable. You don't know anything about its state, but, as an example, any container is empty, or is non-empty, so a moved-from container is also either empty or non-empty. Which of those is unspecified, but your program can check, and the standard library implementation must behave as appropriate for the result of your program's check.

  • 2
    I am not sure there's any restriction on a moved from object being "usable". Standard library types, yes, but not any old object. – juanchopanza May 22 '14 at 21:52