c++arraysclass

static arrays defined with unspecified size, empty brackets?


For the C++ code fragment below:

class Foo {
    int a[]; // no error
};

int a[];     // error: storage size of 'a' isn't known

void bar() {
    int a[]; // error: storage size of 'a' isn't known
}

why isn't the member variable causing an error too? and what is the meaning of this member variable?

I'm using gcc version 3.4.5 (mingw-vista special) through CodeBlocks 8.02.

On Visual Studio Express 2008 - Microsoft(R) C/C++ Optimizing Compiler 15.00.30729.01 for 80x86, I got the following messages:

class Foo {
    int a[]; // warning C4200: nonstandard extension used : zero-sized array in struct/union - Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
};

int a[];

void bar() {
    int a[]; // error C2133: 'a' : unknown size
}

Now, this needs some explaination too.


Solution

  • C99 supports something called a 'flexible' array member that is allowed to be the last member of a struct. When you dynamically allocate such a struct you can increase the amount requested from malloc() to provide for memory for the array.

    Some compilers add this as an extension to C90 and/or C++.

    So you can have code like the following:

    struct foo_t {
        int x;
        char buf[];
    };
    
    
    void use_foo(size_t bufSize)
    {
        struct foo_t* p = (foo_t*) malloc( sizeof( struct foo_t) + bufSize);
        
        int i;
        
        for (i = 0; i < bufSize; ++i) {
            p->buf[i] = i;
        }
    }
    

    You can't define a struct with a flexible array member directly (as a local or a global/static variable) as the compiler won't know how much memory to allocate for it.

    I'm honestly not sure how you'd easily use such a thing with C++'s new operator - I think you'd have to allocate the memory for the object using malloc() and use placement new. Maybe some class/struct specific overload of operator new could be used...