0

When I first posted this related question I thought I had hit some weird edge-case that possibly included undefined behavior. However, if you read the most recent update there, you will see that a much simpler example also doesn't work. Test the example here.

struct S
{
    int a{};
    enum{} b : 1;
    enum{} c : 1;
};

auto test()
{
    return S{}; //Buffer overrun on this line
}

The compiler helpfully informs us that it's doing something wrong here:

warning C4789: buffer '' of size 8 bytes will be overrun; 8 bytes will be written starting at offset 4

struct S is 8 bytes, as the compiler has correctly figured out. However, in its attempt to construct an instance of this struct, it ends up writing 12 bytes in total. This particular example also demonstrates the issue without any optimizations enabled, unlike the original in the related question.

All the VC++ compilers on Compiler Explorer demonstrate this incorrect code generation, although only the more recent ones warn about it. I am asking this separate question to find out if this issue has always existed, or if it's a somewhat recent regression. If it has always been there, it must have been pure luck that bit-fields have worked for so long. So to make it clear, VS 2017 and VS 2019 are known to be affected, but I don't have the earlier versions installed. If someone else could test those and write the results here, and/or explain why this problem occurs with the VC++ compilers and not GCC/Clang, that would be very helpful.

I hope this is not the wrong place to ask for this.

  • C++11's field initializer syntax has caused quite a few bugs in MSVC++. Must have been done by Jimmy. Use int a; without the {} as a workaround. Similar bug report [is here](https://developercommunity.visualstudio.com/content/problem/495188/bitfield-aggregate-initialization.html) but not fixed in VS2019 for this specific case. Use Help > Send Feedback > Report a Problem. – Hans Passant Sep 23 '19 at 09:04
  • @HansPassant yes I know that the int a{}; triggers it here in this case. A user-provided default constructor [can also trigger the issue](https://gcc.godbolt.org/z/Z6HuYR). My current workaround is to not construct S with S{} but with S(), however assembly is still not optimal in my code-base. [The bug has already been reported.](https://developercommunity.visualstudio.com/content/problem/741580/incorrect-codegen-causes-buffer-overrun-with-brace.html) – Bendik Hillestad Sep 23 '19 at 10:03

0 Answers0