2

I stumbled on the below code which has been confusing me:

union
{
    struct
    {
        uint32_t Id;
        uint8_t a_data[];
    }vendor;
    uint8_t avp[0];
}data;

This compiles fine with g++ 7.2.1, but I'm not able to understand why. How is there no need to provide the size while defining a_data? How can avp have size zero?

Vishal Sharma
  • 1,670
  • 20
  • 55
  • `a_data[]` is C99 standard and not universally supported by C++ compilers, Use `uint8_t avp[0];` as flexible member is exclusively GCC extension for same purpose and should not be used at all. It comes back to 1969. Some other compiler may treat it as array of zero size and any access would be out-of-bounds. – Swift - Friday Pie Sep 13 '18 at 06:22

1 Answers1

5

That's a flexible array member and is technically not part of C++ (it's a C-only feature).

Some compilers (especially GCC) are happy to add features from C as extensions to C++. As such it's not portable and you should avoid such code as much as possible.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • It's because GCC is C compiler and that's feature of ISO C99... G++ is C++ compiler that retains features of GCC. I wonder how they treat strict aliasing when dealing with this. At least three large platforms use this extension, WIndows API is written using it and I was catching my coworkers porting this in their code from Windows to Linux. Because they think it's standard. But Windows API also written with functions that have several entry points. – Swift - Friday Pie Sep 13 '18 at 06:11
  • This is one terrifying way to initialize a struct object, but very nice to know! – Frederik.L Sep 13 '18 at 06:13
  • 1
    @Swift-FridayPie I use the term "GCC" as an abbreviation of "GNU Compiler Collection" (it's how it's officially used). And no matter what, the `gcc` and `g++` *programs* can compile both C and C++ source files. The difference between the frontend-programs `gcc` and `g++` is some of the flag it passes to the actual compiler and the linker. – Some programmer dude Sep 13 '18 at 06:13
  • @Frederik.L there was time when libjpeg had vulnerability based on use of this feature. It's easy to describe file format which got fixed headers stacked at its beginning this way. Problem is how to manage memory access thereafter. – Swift - Friday Pie Sep 13 '18 at 06:17