Zero sized arrays in base classes?

F

fabio

Hello,
zero-sized arrays (which I find very useful, since I do a lot of
packet-style programming with circular buffers) cannot be declared
if they're in a struct/class that later will be inherited (i.e. in
a base class), we know.

In ANSI C++ you can't actually instantiate such a structure, if I'm
not mistaken. Example:

struct MyBaseClass {
char * Name;
int Properties;
int Flags;
int Size;
unsigned char Data[0];
};

works as long as you then don't use it to create another struct/class,
for example:

class MyDerivedClass : MyBaseClass {
int AddedStuff;
};

The above generates an error, not a warning.

Which I find an annoying limitation. It would be perfectly justified
because while inheriting, it's not possible to know where to add the
new stuff if there's an unknown-size object before. But I want it as
a label, so it would be perfectly doable in the specific, [0] size
case (you see, I inherited my programming style from assembly). Of
course it would be impossible in a [] case (I'm talking
syntactically here, unfortunately for C/C++ [] and [0] seem to be
the same thing, but they shouldn't really).

Is there a fix or a serious workaround for this? Even if it's not
perfectly ANSI C++ compliant. BTW: putting [0] instead of [] as I
mentioned doesn't help. Neither the use of void (I had to try ;) ).
Labels can't be declared there. What a disappointment.

Actually the way I work around it is annoying too:

I remove the "unsigned char Data[0];" part from the BaseClass, and
add it to the derived class. But since Data needs to be used by
members of BaseClass (that's what I want in the end, otherwise the
whole OOP of C++ becomes far from ideal for me), I access the Data
via a pointer to BaseClass+sizeof(BaseClass), eventually casted to
a pointer to the derivedclass when I want to pass it to a function
that accepts that type. Ugly, but as I said I like to think in asm-
like terms (to be more exact, in "memory, labels and types" terms).

Thanks for any hints xor suggestions, and have a nice day!
Fabio
 
A

Alf P. Steinbach

* (e-mail address removed):
zero-sized arrays (which I find very useful, since I do a lot of
packet-style programming with circular buffers) cannot be declared
if they're in a struct/class that later will be inherited (i.e. in
a base class), we know.

That's correct, because they're not allowed at all.

In ANSI C++ you can't actually instantiate such a structure, if I'm
not mistaken. Example:

struct MyBaseClass {
char * Name;
int Properties;
int Flags;
int Size;
unsigned char Data[0];
};

works as long as you then don't use it to create another struct/class,

That's not ISO C++, that's some compiler vendor's language extension.


[snip]
I want it as a label

Generally it would be better to use techniques that don't require a
label, for whatever it is that you do, but as a workaround until then,
can't you use sizeof(MyBaseClass)?
 
M

Michiel.Salters

Hello,
zero-sized arrays (which I find very useful, since I do a lot of
packet-style programming with circular buffers) cannot be declared
if they're in a struct/class that later will be inherited (i.e. in
a base class), we know.

In ANSI C++ you can't actually instantiate such a structure, if I'm
not mistaken. Example:

struct MyBaseClass {
char * Name;
int Properties;
int Flags;
int Size;
unsigned char Data[0];
};

What's the point? You have sizeof(MyBaseClass) to tell you where
MyBaseClass ends. And often, you don't even need that: Incrementing
a MyBaseClass * automatically increments it in sizeof(MyBaseClass)
steps.

HTH,
Michiel Salters
 
E

Earl Purple

Hello,
zero-sized arrays (which I find very useful, since I do a lot of
packet-style programming with circular buffers) cannot be declared
if they're in a struct/class that later will be inherited (i.e. in
a base class), we know.

In ANSI C++ you can't actually instantiate such a structure, if I'm
not mistaken. Example:

struct MyBaseClass {
char * Name;
int Properties;
int Flags;
int Size;
unsigned char Data[0];
};

works as long as you then don't use it to create another struct/class,

That is very much a C struct, except that normally the array is given a
size 1. But when you allocate (with malloc) you allocate sizeof( struct
MyBaseClass ) + bufLen - 1. which then allows you to put more bytes
into the Data section.

Obviously there is no such thing as "deriving" from a C struct.
 
K

Kai-Uwe Bux

Earl said:
Hello,
zero-sized arrays (which I find very useful, since I do a lot of
packet-style programming with circular buffers) cannot be declared
if they're in a struct/class that later will be inherited (i.e. in
a base class), we know.

In ANSI C++ you can't actually instantiate such a structure, if I'm
not mistaken. Example:

struct MyBaseClass {
char * Name;
int Properties;
int Flags;
int Size;
unsigned char Data[0];
};

works as long as you then don't use it to create another struct/class,

That is very much a C struct, except that normally the array is given a
size 1. But when you allocate (with malloc) you allocate sizeof( struct
MyBaseClass ) + bufLen - 1. which then allows you to put more bytes
into the Data section.

Obviously there is no such thing as "deriving" from a C struct.

I only have a little issue with the very last line.

In C++, you can derive from a struct:

struct X {

int a;

}; // X

struct Y : public X {

int b;

}; //Y

int main ( void ) {
Y y;
y.a = 1;
y.b = 0;
}


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top