2

Consider the following code

struct dummy1 {
    int b;
    dummy1();
};
struct dummy {

    dummy1 a[];
    int c;
    dummy();

};
int main()
{
    dummy foo;
    foo.a[0].b = 5;
    foo.a[1].b = 6;
    return 0;
}
dummy::dummy()
    :a()
    ,c()
{

}
dummy1::dummy1()
    : b()
{

}

I am getting an error "Incomplete type is not allowed" , As far as i know we get this error if the structure we are defining the object of is not defined or the header file is not included which is not the case strangely when I define my int c before a[] the code works so replacing this

struct dummy {
    int c;
    dummy1 a[];
    dummy();

};

the code works just fine, Any ideas why this might be happening ?

P.S I am using VS2015

5
  • 3
    This is a flexible array member which is not allowed in C++, so is probably a compiler extension.
    – interjay
    Commented Jun 3, 2019 at 11:59
  • Oh thanks! I didn't know that it seems that this flexible member array should only be the last member of the struct , makes sense. Commented Jun 3, 2019 at 12:03
  • @interjay: You're basically right, but a[] would have to be the last member in the struct.
    – Anton F.
    Commented Jun 3, 2019 at 12:05
  • @AntonF., Yes, that's why OP got the error.
    – interjay
    Commented Jun 3, 2019 at 12:06
  • Ok, I was too late. But I would use separate allocation for a if possible to fit the standard.
    – Anton F.
    Commented Jun 3, 2019 at 12:07

2 Answers 2

5

dummy1 a[]; is not valid. You must define the size of your array. If you don't know what size array you need in advance, use std::vector instead of a raw array:

struct dummy {
    std::vector<dummy1> a;
    int c;
};

int main()
{
    dummy foo;
    foo.a.resize(2);
    foo.a[0].b = 5;
    foo.a[1].b = 6;
}

The reason it compiles when you swap the order of your members is a feature of C called "flexible array members" that some compilers provide as an extension to C++. This allows you to declare an array-of-unknown-bound as the last member of a struct. No memory is reserved for that array when you declare an automatic or static variable of that type though. It's intended to be used with malloc:

struct dummy {
    int c;
    dummy1 a[];
};

int main() {
    // allocate storage for 5 dummy1 objects in our flexible array
    dummy* foo = malloc(sizeof(dummy) + 5 * sizeof(dummy1));
    foo->a[0].b = 5;
    foo->a[1].b = 6;
    free(foo);
    return 0;
}

Note that this is not a standard part of C++. It is a non-standard compiler extension, and does not play well with many C++ features. Compilers likely provide this extension mostly for compatibility with libraries written in C.

1

I guess it is the array a with size 0 in dummy. The standard doesn’t allow this.

Try:

struct dummy {

   dummy1* a;
   int c;
   dummy();
};

Or:

struct dummy {

   dummy1 a[1];
   int c;
   dummy();
};

Not the answer you're looking for? Browse other questions tagged or ask your own question.