Novice_Developer
Novice_Developer

Reputation: 1492

Strange incomplete type is not allowed error

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

Upvotes: 2

Views: 1130

Answers (2)

Anton F.
Anton F.

Reputation: 486

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();
};

Upvotes: 1

Miles Budnek
Miles Budnek

Reputation: 30494

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.

Upvotes: 5

Related Questions