473,387 Members | 1,425 Online

# Tail space in struct within struct

Consider the following structures:

struct bar {
int i;
float f;
unsigned char tail[1];
};
struct foo {
struct bar b1;
unsigned char _b1tail[B1N];
struct bar b2;
unsigned char _b2tail[B2N];
};

Can I rely on the order of members such that _b1tail will occupy at
least B1N bytes between b1 and b2?:

&foo->b2 - &foo->b1 >= sizeof(struct bar) + BN

So I can use &foo->b2 as the effective end of _b1tail?

Thanks,
Mike
Nov 14 '05 #1
3 2424

"Michael B Allen" <mb*****@ioplex.com> wrote
Consider the following structures:

struct bar {
int i;
float f;
unsigned char tail[1];
};
struct foo {
struct bar b1;
unsigned char _b1tail[B1N];
struct bar b2;
unsigned char _b2tail[B2N];
};

Can I rely on the order of members such that _b1tail will occupy at
least B1N bytes between b1 and b2?:

&foo->b2 - &foo->b1 >= sizeof(struct bar) + BN

So I can use &foo->b2 as the effective end of _b1tail?

Yes, but it is what Denis Ritchie calls an "unwarranted chumminess with the
implementation".
I think that the member array "tail" should be zero-sized, however, to
prevent the compiler inserting a trap at position two.
Nov 14 '05 #2

On Sat, 23 Oct 2004, Malcolm wrote:
"Michael B Allen" <mb*****@ioplex.com> wrote

struct bar {
int i;
float f;
unsigned char tail[1];
};
struct foo {
struct bar b1;
unsigned char _b1tail[B1N];
struct bar b2;
unsigned char _b2tail[B2N];
};

Can I rely on the order of members such that _b1tail will occupy at
least B1N bytes between b1 and b2?:

&foo->b2 - &foo->b1 >= sizeof(struct bar) + BN
Of course you meant something more like

(char*)&foo->b2 - (char*)&foo->b1 >= sizeof(struct bar) + B1N

but following that correction, it's correct; you may assume that.
This is because all struct members come one after another in the order
they're defined in the struct definition.
So I can use &foo->b2 as the effective end of _b1tail?
Yes, but it is what Dennis Ritchie calls an "unwarranted chumminess with
the implementation".

Caveat: It depends what you mean by "use." For example, AFAIK it
invokes undefined behavior to write

((char*)&foo->b2)[-1] = 42; /* modify the "last" byte of |_b1tail| */

because the implementation might have put a padding and/or checksum byte
there, and wantonly changing padding bytes is a Bad Thing. (I could be
wrong about the Standard-mandated effect of changing padding bytes, but
it seems reasonable to me.)
I think that the member array "tail" should be zero-sized, however, to
prevent the compiler inserting a trap at position two.

Bad advice. Last I checked, zero-sized objects were not supported in C.
Maybe if Michael explains what he's really trying to do, a better (more
portable) solution will be reached.

HTH,
-Arthur
Nov 14 '05 #3
On Sat, 23 Oct 2004 12:38:06 -0400, Arthur J. O'Dwyer wrote:
So I can use &foo->b2 as the effective end of _b1tail?

Yes, but it is what Dennis Ritchie calls an "unwarranted chumminess
with the implementation".

Caveat: It depends what you mean by "use." For example, AFAIK it
invokes undefined behavior to write

((char*)&foo->b2)[-1] = 42; /* modify the "last" byte of |_b1tail| */

Maybe if Michael explains what he's really trying to do, a better (more
portable) solution will be reached.

Ok. The tail members are bitmaps that are different sizes depending on
needs. I have a struct with several of these object/bitmap pairs that
I initialize with a function like:

int
bar_init(struct bar *b, void *blim, float f)
{
memset(b, 0, blim - (void *)b);
b->blim = blim;
if (something_init(&b->something, f) == -1) {
return -1;
}
b->tail[0] = 0x01; /* don't use bit 0 */
return 0;
}

So when I call this initializer I need to know the end of the tail so
that my bitset rountines know where to stop. Rather than try to compute
this point I reasoned that provided the order of members is maintained
that the member following the tail is and effective blim.

if (bar_init(&foo->b1, &foo->b2, 1.1) == -1 ||
bar_init(&foo->b2, &foo->b3, 2.2) == -1 ||
bar_init(&foo->b4, foo + 1, 3.3) == -1) {
return -1;
}

So based on what you've said I think I'm ok.

Thanks,
Mike
Nov 14 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.