Point me in the right direction

Carl Paukstis carlp at iscuva.ISCS.COM
Fri Feb 24 07:24:53 AEST 1989


In article <3735 at arcturus> evil at arcturus.UUCP (Wade Guthrie) writes:
>In article <1043 at auspex.UUCP>, guy at auspex.UUCP (Guy Harris) writes:
>> Of course, adding:
>> 	#define N_FCONSTS (sizeof(fund_consts)/sizeof(double)) 
>
>[and Guy said:] 
>
>> So far, so good - this is an old C trick, which is quite useful, but may
>> not be known as well as it should be - but...
>
>[and Wade says:]
>
>This is all well and good, but what about arrays of structures?  Am I
>S.O.L. because of inter-array-element padding if I:
>
>	struct already_defined snarf[] = {...};
>
>and then try to get the size by doing:
>
Method A:
>	#define N_WHATEVER (sizeof(snarf)/sizeof(struct already_defined))

Nope, you're not S.O.L.  This is well-defined in the pANS (at least in my
January draft).   From 3.3.3.4 (The sizeof operator):
"When applied to an operand that has structure or union type, the result is
the total number of bytes in such an object, including internal AND
TRAILING padding."  [emphasis mine]  

Then, from 3.5.2.1 (Structure and union specifiers):
"A pointer to a structure object, suitably cast, points to its initial
member [...], and vice versa.  There may therefore be unnamed holes within
a structure object, but not at its beginning, as necessary to achieve the
appropriate alignment.  There may also be unnamed padding AT THE END of a
structure, as necessary to achieve appropriate alignment were the structure
to be a member of an array." [emphasis mine]

I read this to require sizeof(struct already_defined) to include whatever
space is necessary to make the structure align properly, AND space
necessary to make the NEXT structure in an array align properly.

>or can I (portably)
>
>	int size;
>	. . .
Method B:
>	size = sizeof(snarf)/(&snarf[1]-&snarf[0]);
>
>(assuming, of course, that snarf has at least 2 elements. . .)

I believe I'd choose the first method.  I'm sure you realize that the above
code will always set "size" to "sizeof(snarf)", since the parenthesized
portion after the division operator will always evaluate to 1.

If you cast, e.g. 
     size = sizeof(snarf)/((char *)&snarf[1]-(char *)&snarf[0]);
or maybe
 size = sizeof(snarf)/((char *)((void *)&snarf[1])-(char *)((void *)&snarf[0]));
I'm not SURE this is portable, but I can't offhand see any reason at least
the second version wouldn't be.  It's gawdawful ugly, though.

I use method A, and have not yet had it fail me with any compiler I have
access to. (Okay, "to which I have access.")
-- 
Carl Paukstis    +1 509 927 5600 x5321  |"The right to be heard does not
                                        | automatically include the right
UUCP:     carlp at iscuvc.ISCS.COM         | to be taken seriously."
          ...uunet!iscuva!carlp         |                  - H. H. Humphrey



More information about the Comp.lang.c mailing list