Is this valid C?

  • Thread starter andrew queisser
  • Start date
A

andrew queisser

Is the following code valid C?

typedef struct
{
char x[128];
} foo;

typedef struct
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
} bar;


I'd like to use this construct to ensure keeping member sizes in two
structures in lockstep but I'm not sure if it's really portable.

Thanks,
Andrew
 
E

Eric Sosman

andrew queisser wrote On 06/06/06 13:24,:
Is the following code valid C?

typedef struct
{
char x[128];
} foo;

typedef struct
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
} bar;


I'd like to use this construct to ensure keeping member sizes in two
structures in lockstep but I'm not sure if it's really portable.

It looks all right to me. I think I'd prefer to
see it done differently, though:

#define XCOUNT 128

typedef struct {
char x[XCOUNT];
} foo;

typedef struct {
char sameSizeAsFooX[XCOUNT];
} bar;

A better solution (sometimes) would be to wrap the
common elements in their own substructure:

typedef struct {
char x[128];
} xstuff;

typedef struct {
double trouble;
xstuff boo;
double scotch;
} foo;

typedef struct {
xstuff booboo, bluegoo, zoocrew;
short snort;
} bar;

Much depends on your reasons for wanting to keep
these things' sizes synchronized.
 
A

andrew queisser

Eric Sosman said:
andrew queisser wrote On 06/06/06 13:24,:
Is the following code valid C?

typedef struct
{
char x[128];
} foo;

typedef struct
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
} bar;


I'd like to use this construct to ensure keeping member sizes in two
structures in lockstep but I'm not sure if it's really portable.

It looks all right to me. I think I'd prefer to
see it done differently, though:

#define XCOUNT 128

typedef struct {
char x[XCOUNT];
} foo;

typedef struct {
char sameSizeAsFooX[XCOUNT];
} bar;
Yes, this is what I normally do (and of course I would use a #define inside
foo anyway) but the problem is that I might change my mind about the size of
foo->x and then I have to search for all occurrences of the #define. With
this new style I can see that my intent was to force one array to be the
same as another one. With the #define the link between the two arrays is not
clear in isolation.

Thanks for the comments,
Andrew
 
F

Fred Kleinschmidt

andrew queisser said:
Eric Sosman said:
andrew queisser wrote On 06/06/06 13:24,:
Is the following code valid C?

typedef struct
{
char x[128];
} foo;

typedef struct
{
char sameSizeAsFooX[ sizeof ((foo *)0)->x ];
} bar;


I'd like to use this construct to ensure keeping member sizes in two
structures in lockstep but I'm not sure if it's really portable.

It looks all right to me. I think I'd prefer to
see it done differently, though:

#define XCOUNT 128

typedef struct {
char x[XCOUNT];
} foo;

typedef struct {
char sameSizeAsFooX[XCOUNT];
} bar;
Yes, this is what I normally do (and of course I would use a #define
inside foo anyway) but the problem is that I might change my mind about
the size of foo->x and then I have to search for all occurrences of the
#define. With this new style I can see that my intent was to force one
array to be the same as another one. With the #define the link between the
two arrays is not clear in isolation.

All occurrences of the #define? I surely hope you would only #define it
once!
If you have multiple files, put the #define in an include file that is
included in all of the source files.

If the macro name is chosen meaningfully, it is perfectly clear about the
size and what it means: the same size as anything declared using XCOUNT.
Or name it FOO_XCOUNT if you want to point out that 'foo' is the
primary driver.
 
A

andrew queisser

Yes, this is what I normally do (and of course I would use a #define
All occurrences of the #define? I surely hope you would only #define it
once!
If you have multiple files, put the #define in an include file that is
included in all of the source files.

Right, #define once, in one header file.
If the macro name is chosen meaningfully, it is perfectly clear about the
size and what it means: the same size as anything declared using XCOUNT.
Or name it FOO_XCOUNT if you want to point out that 'foo' is the
primary driver.

That goes a long way toward keeping things organized. However, if I go back
to a set of source files I haven't worked on in a long time I might decide
that foo->x really needs to be a different size, perhaps based on a
different #define (e.g. maybe it should be exactly MAX_PATH+1 or something
like that.) I could now #define FOO_XCOUNT to be MAX_PATH+1 but I'd really
like to see the meaningful MAX_PATH+1 in the array declaration so at that
point I have to grep through my sources to find out who else is using
FOO_XCOUNT. With this new construct I'm using it's automatic.

Andrew
 

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,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top