26

The code below prints garbage (or zeroes) if compiled with VC++ 2017 and "1122" if compiled with GCC or Clang (https://rextester.com/JEV81255). Is it bug of VC++ or I'm missing something here?

#include <iostream>

struct Item {
    int id;
    int type;
};

int main()
{
    auto items = new Item[2]
    {
        { 1, 1 },
        { 2, 2 }
    };

    std::cout << items[0].id << items[0].type;
    std::cout << items[1].id << items[1].type;
}

At the same time it works if elements are of a primitive type (like int).

L. F.
  • 19,445
  • 8
  • 48
  • 82
user10101
  • 1,704
  • 2
  • 20
  • 49
  • 7
    Yeah, it has been broken for several years. The stuff inside `{}` is completely ignored so you can write some nonsense like `auto items = new Item[2] { { std::cout, " sdf" , 0.3f} };`. I've tried to find related issues at VS feedback hub (at least the one I've created) but the search there is broken as well... – user7860670 Sep 04 '19 at 10:53
  • 3
    Following up @VTT comment still very broken, live: https://godbolt.org/z/Fn6dgp – Richard Critten Sep 04 '19 at 10:55
  • 3
    @rafix07 It is still broken in VS2019 – user7860670 Sep 04 '19 at 10:58
  • VS2019 Code Analysis gives: `warning C6001: Using uninitialized memory 'items[0].id'`. But `clang-cl` inside VS2019 works fine. – Adrian Mole Sep 04 '19 at 11:00
  • 3
    That's scary. And the fact MS doesn't fix this is even more scary... – Jabberwocky Sep 04 '19 at 11:17
  • This works with `std::vector` but not `std::array`. The pre-compiler complains of "too many initializer values" and the actual compiler throws a `C2440` error with the note: "Invalid aggregate initialization." The above code as-is only warns about accessing unintialized memory. – Casey Sep 10 '19 at 19:16
  • 1
    This is fixed in MSVC 19.27. – ecatmur Mar 10 '22 at 10:38

1 Answers1

1

I got it to work by writing the following but then the data is not stored on the Heap.

Item items[] {
    { 1, 1 },
    { 2, 2 }
};

If you need it on the heap use the solution below it seems to work with the vc++ compiler. (Note that this is only a workaround and does nt fix the underlying problem):

Item* Items[2];
Items[0] = new Item{3,3};
Items[1] = new Item{4,4};

std::cout << (*Items[0]).id << (*Items[0]).type << std::endl;
std::cout << (*Items[1]).id << (*Items[1]).type << std::endl;

Altenatively you can create the Array using the first option and then copy it into an Array on the heap like this:

Item items[2]{
    {1,1},
    {2,2}
};

Item* hitem = new Item[2];
for(int i = 0; i < 2; i++){
    hitem[i].id = items[i].id + 4;
    hitem[i].type = items[i].type + 4;
}

While this is slow it works like it is supposed to even on the vc++ compiler. You can view the whole code here:https://rextester.com/VNJM26393

I don't know why it only works like this...