In C99, you can declare a flexible array member of a struct as such:
struct blah
{
int foo[];
};
However, when someone here at work tried to compile some code using clang in C++, that syntax did not work. (It had been working with MSVC.) We had to convert it to:
struct blah
{
int foo[0];
};
Looking through the C++ standard, I found no reference to flexible member arrays at all; I always thought [0]
was an invalid declaration, but apparently for a flexible member array it is valid. Are flexible member arrays actually valid in C++? If so, is the correct declaration []
or [0]
?
C++ was first standardized in 1998, so it predates the addition of flexible array members to C (which was new in C99). There was a corrigendum to C++ in 2003, but that didn't add any relevant new features. The next revision of C++ (C++0x) is still under development, and it seems flexible array members aren't added to it.
If you can restrict your application to only require a few known sizes, then you can effectively achieve a flexible array with a template.
If you only want
then you don't need the struct at all an you can simply deal with a malloc'ed/new'ed int array.
If you have some members at the beginning:
then in C++, I suppose you could replace
foo
with afoo
member function:Example use:
The better solution is to declare it as a pointer:
Or better yet, to declare it as a
std::vector
:C++ doesn't support C99 flexible array members at the end of structures, either using an empty index notation or a
0
index notation (barring vendor-specific extensions):As far as I know, C++0x will not add this, either.
However, if you size the array to 1 element:
things are valid, and work quite well. You can allocate the appropriate memory with an expression that is unlikely to have off-by-one errors:
So it's portable between C90, C99 and C++ and works just as well as C99's flexible array members.
Raymond Chen did a nice writeup about this: Why do some structures end with an array of size 1?
Note: In Raymond Chen's article, there's a typo/bug in an example initializing the 'flexible' array. It should read:
The second one will not contain elements but rather will point right after
blah
. So if you have a structure like this:you can do things like this:
In this case
c
will behave as an array with 5int
s but the data in the array will be after thesomething
structure.The product I'm working on uses this as a sized string:
Because of the supported architectures this will consume 8 bytes plus
allocated
.Of course all this is C but g++ for example accepts it without a hitch.