Flexible array fields in C++ classes.

Hello.

When compiling the following C++ code

flex_array_in_class.patch (589 Bytes)

Hi!

Enea Zaffanella wrote:

The impression is that the if-guard condition
    Record->isStruct()
is an overkill and could be replaced by the weaker form
    (Record->isStruct() || Record->isClass())

As I know in C++ the only difference between struct and class is that by default in struct members (and bases) are public and in class -- private.

Has it a sense to look through every place where isStruct() exists and decide whether isClass() should also be there?

I did this, but as I saw there is no such use of both of isStruct() and isClass(). isStruct() and isClass() seems to be used in different places. So I am a bit confused. Maybe some one else who has more knowledge about internals of clang looks at this?

Sorry, if this message is useless.

Hello.

When compiling the following C++ code

struct S {
int size;
int vec[]; // This is OK.
};

class C {
public:
int size;
int vec[]; // This triggers diagnostic.
};

clang complains about the flexible array 'vec' that is found at the end of class C, whereby it accepts the very same thing if at the end of struct S. This is different wrt g++ behavior, which accepts both cases.

$ clang++ -fsyntax-only flex.cc
flex.cc:9:7: error: field has incomplete type 'int []'
int vec[]; // This triggers diagnostic.
     ^
1 diagnostic generated.

Frankly, I'd rather reject both cases in C++. Flexible arrays collide with C++ in a few places, and we need to find those places and address them before enabling this extension. I have the same view toward variable-length arrays in C++ (http://llvm.org/bugs/show_bug.cgi?id=5678): we *can* have the extension, but we need to complain and we need to deal with the various corner cases before enabling the extension. If we aren't strict about this, we'll end up where GCC is now, with a bunch of half-baked extensions.

For example, I wrote this little test:

struct S {
  int size;
  int vec[];
};

struct S2 {
  S s;
  int x;
};

struct T : S { int x; };

template<typename T>
struct X { T t; int x; };

X<S> xs;

Even under -Wall, g++ doesn't complain about anything here... it doesn't complain about the definition of S2, which has a non-static data member ('x') following a non-static data member ('s') that has a flexible array member, nor does it complain about derivation from a class with a flexible array member, which is the moral equivalent of the previous problem. Clang does better (it warns about the first case, along with case where this happens in templates), but misses derivation.

So, Clang is already in the "half-baked" category with this extension to C++. We should either finish the extension or ban it in C++, but we shouldn't extend it 1% and then leave it there.

  - Doug