21

I have the following code:

#include "stdafx.h"
#include <unordered_map>
#include <cassert>
int main()
{
    struct Foo { int a; };
    std::unordered_map<int, Foo> foos{ { 0, { 3 } }, { 1, { 4 } } };
    for (auto &[i, foo] : foos)
    {
        foo.a = 6; //doesn't change foos[i].a
        assert(&foo.a == &foos[i].a); //does not pass
    }

    auto &[i, foo] = *foos.begin();
    foo.a = 7; //changes foo[0].a
    assert(&foo.a == &foos[0].a); //passes
}

My question:

Why doesn't the first assert statement pass while the second passes? Why can't I change the value of a foo in the foos map in a range-based for-loop?

Compiler: MSVS++17 Visual studio 15.3.2

Edit: The code now compiles if copy pasted into a visual studio project.

Jupiter
  • 1,421
  • 2
  • 12
  • 31
  • 10
    MSVC bug. File a bug report. – T.C. Aug 27 '17 at 18:28
  • Please post an example program that will compile. – Jive Dadson Aug 27 '17 at 18:58
  • @JiveDadson I edited my post. – Jupiter Aug 27 '17 at 19:35
  • I concur with T.C. Looks like a bug. Inside the loop, it is treating "foo" as a by-value parameter. – Jive Dadson Aug 28 '17 at 00:03
  • 1
    Bonus bug: It sometimes crashes Intellisense (R). "Visual C++ Package Server has stopped working" – Jive Dadson Aug 28 '17 at 00:29
  • I filed a bug report. Once it is a confirmed bug I will post an answer. Yeej, my second msvc++ bug in like 2-3 months... My teacher recently said to me in response to a problem with his code that compiler bugs are so rare, we can dismiss such an explanation beforehand. Now I beg the differ. – Jupiter Aug 28 '17 at 09:18
  • @Jupiter The C++17 standard isn't even ISO approved yet. It is to be expected that brand new implementations of new features have some bugs. – Felix Glas Aug 29 '17 at 09:09

1 Answers1

10

I posted a bugreport in VS and it is under investigation now.

E. Vakili
  • 1,036
  • 1
  • 10
  • 25
Jupiter
  • 1,421
  • 2
  • 12
  • 31