Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

what's the size of type char foo[3] ?

34 views
Skip to first unread message

Francois Grieu

unread,
Feb 22, 2012, 8:24:26 AM2/22/12
to
I am wondering if (on a conforming hosted implementation of C99)
the following program is guaranteed to output: 3 3

Specifically, I'm afraid that there could be some padding,
either for type foo, or variable bar.

#include <stdio.h>
typedef char foo[3];
int main(void) {
foo bar;
printf("%u %u\n",(unsigned)sizeof(foo),(unsigned)sizeof bar);
return 0;
}
Message has been deleted

Ben Bacarisse

unread,
Feb 22, 2012, 9:06:55 AM2/22/12
to
I was going to say "yes" -- sizeof(char) is 1 and arrays can't have any
padding between the elements -- but then I found I could not, at first
reading, rule out arrays having padding after the last element. It
would be daft, of course, but I can't see why it is not permitted.

I would say your are safe to assume that such things do not occur. The
widely used idiom: sizeof array / sizeof *array relies on it, for one
thing.

--
Ben.
Message has been deleted

Stephen Sprunk

unread,
Feb 22, 2012, 12:02:05 PM2/22/12
to
On 22-Feb-12 08:06, Ben Bacarisse wrote:
> Francois Grieu <fgr...@gmail.com> writes:
>> I am wondering if (on a conforming hosted implementation of C99)
>> the following program is guaranteed to output: 3 3
>>
>> Specifically, I'm afraid that there could be some padding,
>> either for type foo, or variable bar.
>>
>> #include <stdio.h>
>> typedef char foo[3];
>> int main(void) {
>> foo bar;
>> printf("%u %u\n",(unsigned)sizeof(foo),(unsigned)sizeof bar);
>> return 0;
>> }
>
> I was going to say "yes" -- sizeof(char) is 1 and arrays can't have any
> padding between the elements

True. One should not forget that the array elements themselves may
contain padding, but that is extremely unlikely in this case.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

Francois Grieu

unread,
Feb 22, 2012, 12:35:43 PM2/22/12
to
Invoquing that idiom is an excellent idea. It is given in the standard
as 6.5.3.4 (6)
Another use of the sizeof operator is to compute the number of
elements in an array:
sizeof array / sizeof array[0]

Thus I'm ready to assume that after

char bot[3];

indeed sizeof(bot) is 3.


But does that tell us the size of the type foo or of the variable
bar [that would be the case if bar was an "array" in the sense
of 6.5.3.4 (6), but is it?

Ben Bacarisse

unread,
Feb 22, 2012, 1:20:48 PM2/22/12
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>>I was going to say "yes" -- sizeof(char) is 1 and arrays can't have any
>>padding between the elements -- but then I found I could not, at first
>>reading, rule out arrays having padding after the last element. It
>
> It is said, »When applied to an operand that has array type,
> the result is the total number of bytes in the array.«
> in »6.5.3.4 The sizeof operator« of »ISO/IEC 9899:1999 (E)«.

I don't think that helps. It does not say that the total number of
bytes in the array can't be a few more than the minimum required.

Two things do help. (1) Later in the same paragraph "trailing padding"
is explicitly referred to for struct types, so one can, I think, exclude
it for array types simply by the fact that it is *not* mentioned. (2)
The example in paragraph 6. Not normative by itself, but the intent is
made very clear.

--
Ben.

Ben Bacarisse

unread,
Feb 22, 2012, 1:22:44 PM2/22/12
to
Yes, the intent is made 100% clear by that example.

> Thus I'm ready to assume that after
>
> char bot[3];
>
> indeed sizeof(bot) is 3.
>
>
> But does that tell us the size of the type foo or of the variable
> bar [that would be the case if bar was an "array" in the sense
> of 6.5.3.4 (6), but is it?

I can't see why not.

--
Ben.

jacob navia

unread,
Feb 22, 2012, 2:10:40 PM2/22/12
to
Le 22/02/12 14:24, Francois Grieu a écrit :
The size is 3. Padding is of course there, but not in the array. Under
lcc-win the padding is inserted after the array, leaving a byte in the
stack unused, not a big deal this days.

BartC

unread,
Feb 22, 2012, 2:26:09 PM2/22/12
to


"jacob navia" <ja...@spamsink.net> wrote in message
news:ji3ejc$oa9$1...@speranza.aioe.org...
What about in: foo bar[100]; ?

All the compilers I tried showed sizeof(bar) to be 300, so no padding
between elements, yet to me it would seem useful to round each entry up to 4
bytes: that makes it possible to copy an entire 3-byte entry to another
using 32-bit instructions, all the entries start on a preferred alignment,
and index calculation is simpler.

(However I'm not sure I'd be happy about a foo[33] element rounded up to
64...)

--
Bartc

Barry Schwarz

unread,
Feb 22, 2012, 3:07:34 PM2/22/12
to
Does changing the definition of bar to
foo bar[2]
and then applying 6.2.5-20 and 6.5.2.1-4 effectively eliminate the
possibility of "end of array padding"?

How about 6.5.3.4-3 which discusses sizeof applied to arrays? It
mentions internal and trailing padding for structure and union types
but not for arrays.

How about footnote 94 which talks about sub-arrays being adjacent?

--
Remove del for email

jacob navia

unread,
Feb 22, 2012, 4:28:47 PM2/22/12
to
Le 22/02/12 15:06, Ben Bacarisse a écrit :
> Francois Grieu<fgr...@gmail.com> writes:
>
>> I am wondering if (on a conforming hosted implementation of C99)
>> the following program is guaranteed to output: 3 3
>>
>> Specifically, I'm afraid that there could be some padding,
>> either for type foo, or variable bar.
>>
>> #include<stdio.h>
>> typedef char foo[3];
>> int main(void) {
>> foo bar;
>> printf("%u %u\n",(unsigned)sizeof(foo),(unsigned)sizeof bar);
>> return 0;
>> }
>
> I was going to say "yes" -- sizeof(char) is 1 and arrays can't have any
> padding between the elements -- but then I found I could not, at first
> reading, rule out arrays having padding after the last element. It
> would be daft, of course, but I can't see why it is not permitted.
>

Of course it is permitted. The padding bytes just aren't part of the
array!


Ben Bacarisse

unread,
Feb 22, 2012, 5:02:49 PM2/22/12
to
I don't think so. Both of those apply equally to

struct { char a[3]; } sa[2];

and we know that the sizeof sa[0] need not be 3.

> How about 6.5.3.4-3 which discusses sizeof applied to arrays? It
> mentions internal and trailing padding for structure and union types
> but not for arrays.

Yes, that's enough for me, though it's a shame it's a demonstration by
omission.

> How about footnote 94 which talks about sub-arrays being adjacent?

For me, no. If the supposed padding is part of the array (like it is
with a struct) the arrays are still adjacent.

--
Ben.
Message has been deleted

Ben Bacarisse

unread,
Feb 22, 2012, 11:30:03 PM2/22/12
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>>I don't think that helps. It does not say that the total number of
>>bytes in the array can't be a few more than the minimum required.
>
> There is:
>
> »There may be unnamed padding at the end of a
> structure or union.« 6.7.2.1p15, ISO/IEC 9899:1999 (E)
>
> But no such license is given for an array.

Yes, as I've already said, I think that silence is the strongest
argument. That and the explicit example of dividing the array size by
the element size to get the length.

--
Ben.

Keith Thompson

unread,
Feb 23, 2012, 2:03:43 AM2/23/12
to
Dividing the array size by the element size to get the length would
still work if the amount of padding at the end of an array is less than
the size of an element.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Nick Keighley

unread,
Feb 23, 2012, 3:03:30 AM2/23/12
to
On Feb 23, 7:03 am, Keith Thompson <ks...@mib.org> wrote:
> Ben Bacarisse <ben.use...@bsb.me.uk> writes:
> > r...@zedat.fu-berlin.de (Stefan Ram) writes:
> >> Ben Bacarisse <ben.use...@bsb.me.uk> writes:
> >>>I don't think that helps.  It does not say that the total number of
> >>>bytes in the array can't be a few more than the minimum required.
>
> >>   There is:
>
> >>       »There may be unnamed padding at the end of a
> >>       structure or union.« 6.7.2.1p15, ISO/IEC 9899:1999 (E)
>
> >>   But no such license is given for an array.
>
> > Yes, as I've already said, I think that silence is the strongest
> > argument.  That and the explicit example of dividing the array size by
> > the element size to get the length.
>
> Dividing the array size by the element size to get the length would
> still work if the amount of padding at the end of an array is less than
> the size of an element.

but in the case of a char array...

James Dow Allen

unread,
Feb 23, 2012, 3:25:05 AM2/23/12
to
This discussion reminds me of a true story from 24 years ago that might
interest or amuse. I wanted to look at the label on a disk so adopted a
"minimum keystroke" solution:
cp /dev/rsd0b copy_of_label
^C
To my surprise, the data in 'copy' was scrambled, i.e. odd and even
shorts were swapped. (Or maybe I just got 'kernel panic.' After all
these years, I may be conflating two related stories. In any event the
'cp' did not do what it should.)

The error was quite repeatable: running 'cp' on any raw scsi partition
would exhibit the same problem with that release. I'll guess it wasn't
something users did a lot. :-) And, every time 'cp' was recompiled
after minor changes it had a 50-50 chance of functioning correctly.

There were four bugs or bug-like features interacting:
(1) The SCSI controller hardware operated properly only on 4-byte
aligned buffer addresses.
(2) The SCSI driver neglected to cheeck for that alignment.
(3) The program cp.c (which used mmap() for most reads) did reads from
special devices with simply
char buffer[512];
read(infd, buffer, 512);
(4) The cc compiler, faced with a declaration like "char buffer[512]",
saw fit to guarantee 2-byte alignment, but not 4-byte alignment.

I thought this strange episode had instructive features. The clearest
bug might be (1), but it was more-or-less unfixable. Why make a
complicated hardware change to accomodate a yokel who reads disk-labels
with 'cp'? (2) was a blatant stupidity, but correcting it wouldn't
completely solve the problem: The yokel would still get IO_error,
though that is much better than scrambled data or kernel panic.

Neither (3) nor (4) were considered "bugs" -- both the compiler and cp.c
were doing that which they were allowed to do by specs. At the same
time, it seemed both simple and appropriate to fix the problem by
amending cp.c and/or the compiler.

cp.c could be fixed with, for example (:-) )
char xbuffer[512+2];
#define buffer (xbuffer + (2&(int)xbuffer))
And, it seemed possibly sound to add the following logic to the C
compiler:
/* If the character array size is a multiple of 512 , then
* force it to be at least 4-byte aligned unless the array is
* inside a structure. Any storage wastage will be quite small,
* and it's likely to boost performance at least slightly, as well
* as fixing bugs like 'cp /dev/rsd0b.'
*/

I was working as a contractor for a large company, and reported the
situation, through channels to the hardware group's ambassador to the
guru group. I wish I'd saved the e-mail he sent back. It was something
like this:
> I have been to the mountaintop, and the following is
> inscribed in stone:
> The alignment requirement for character arrays is Two,
> and Two is the alignment requirement for character arrays.

A fix for cp.c would take 2 minutes of coding labor (no, I wouldn't
really fix it as above) and several hours in the Bug Tracking and
Approval program. cp's maintainer was uninterested: his program "did
nothing wrong."

AFAIK, 24 years later a 'cp /dev/rsd0b' still has a 50-50 chance of
failure. :-)

James Dow Allen

Ben Bacarisse

unread,
Feb 23, 2012, 7:41:04 AM2/23/12
to
Keith Thompson <ks...@mib.org> writes:

> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>>>>I don't think that helps. It does not say that the total number of
>>>>bytes in the array can't be a few more than the minimum required.
>>>
>>> There is:
>>>
>>> »There may be unnamed padding at the end of a
>>> structure or union.« 6.7.2.1p15, ISO/IEC 9899:1999 (E)
>>>
>>> But no such license is given for an array.
>>
>> Yes, as I've already said, I think that silence is the strongest
>> argument. That and the explicit example of dividing the array size by
>> the element size to get the length.
>
> Dividing the array size by the element size to get the length would
> still work if the amount of padding at the end of an array is less than
> the size of an element.

Yes, but it would fail in some other cases. In particular, it answers
the original question: an N-element char array must have size N for this
idiom to work.

--
Ben.

Scott Fluhrer

unread,
Feb 23, 2012, 1:48:44 PM2/23/12
to

"James Dow Allen" <gm...@jamesdowallen.nospam> wrote in message
news:XnsA0029CCBE7C...@178.63.61.175...
I wouldn't call that a "bug" per se, but instead a hardware limitation.
Hardware often have limitations (sometimes considerably more bizarre than
that); we just have to live with it.

> Why make a
> complicated hardware change to accomodate a yokel who reads disk-labels
> with 'cp'? (2) was a blatant stupidity, but correcting it wouldn't
> completely solve the problem: The yokel would still get IO_error,
> though that is much better than scrambled data or kernel panic.

IMHO, the Right Thing for the driver to do is detect this case, and if it
the alignment was wrong, copy the data via an aligned temp buffer. Yes,
this is a pain and a major performance hit (if the user gives an unaligned
buffer); however, running slowly is better than quickly doing this wrong
thing.

And, yes, in the past, I have written a number of device drivers; this is
part of what you have to deal with. The hardware provides services
(possibly with limitations); the OS expects services (possibly without those
limitations); any gap between the two is ultimately up to the device driver
to cover.

>
> AFAIK, 24 years later a 'cp /dev/rsd0b' still has a 50-50 chance of
> failure. :-)

:-(

--
poncho


io_x

unread,
Feb 24, 2012, 2:18:45 AM2/24/12
to

"James Dow Allen" <gm...@jamesdowallen.nospam> ha scritto nel messaggio
news:XnsA0029CCBE7C...@178.63.61.175...
> There were four bugs or bug-like features interacting:
> (1) The SCSI controller hardware operated properly only on 4-byte
> aligned buffer addresses.
> (2) The SCSI driver neglected to cheeck for that alignment.

had would to detect that and return error?
it is easy to say for a pointer pP
if( ( ((char*)pP)&3)!=0 ) goto error; // this would check aligned to 4 bytes?
?

> (3) The program cp.c (which used mmap() for most reads) did reads from
> special devices with simply
> char buffer[512];
> read(infd, buffer, 512);
> (4) The cc compiler, faced with a declaration like "char buffer[512]",
> saw fit to guarantee 2-byte alignment, but not 4-byte alignment.
...
> Neither (3) nor (4) were considered "bugs" -- both the compiler and cp.c
> were doing that which they were allowed to do by specs. At the same
> time, it seemed both simple and appropriate to fix the problem by
> amending cp.c and/or the compiler.
>
> cp.c could be fixed with, for example (:-) )
> char xbuffer[512+2];

i would write something as:
double dbuffer[512/sizeof(double)];
/* suppose sizeof(double)=2^n < 512
and double aligned >= 4chars
if one know that double has to be 64bits for standard
should be ok for me
*/
char *buffer;
buffer=(char*) dbuffer;

Philip Lantz

unread,
Feb 24, 2012, 2:51:59 AM2/24/12
to
James Dow Allen wrote:
>
> This discussion reminds me of a true story from 24 years ago that might
> interest or amuse. I wanted to look at the label on a disk so adopted a
> "minimum keystroke" solution:
> cp /dev/rsd0b copy_of_label
> ^C
> To my surprise, the data in 'copy' was scrambled, i.e. odd and even
> shorts were swapped.
>
> There were four bugs or bug-like features interacting:
> (1) The SCSI controller hardware operated properly only on 4-byte
> aligned buffer addresses.
> (2) The SCSI driver neglected to cheeck for that alignment.
> (3) The program cp.c (which used mmap() for most reads) did reads from
> special devices with simply
> char buffer[512];
> read(infd, buffer, 512);
> (4) The cc compiler, faced with a declaration like "char buffer[512]",
> saw fit to guarantee 2-byte alignment, but not 4-byte alignment.
>
> I thought this strange episode had instructive features. The clearest
> bug might be (1), but it was more-or-less unfixable. Why make a
> complicated hardware change to accomodate a yokel who reads disk-labels
> with 'cp'? (2) was a blatant stupidity, but correcting it wouldn't
> completely solve the problem: The yokel would still get IO_error,
> though that is much better than scrambled data or kernel panic.
>
> Neither (3) nor (4) were considered "bugs" -- both the compiler and cp.c
> were doing that which they were allowed to do by specs. At the same
> time, it seemed both simple and appropriate to fix the problem by
> amending cp.c and/or the compiler.
>
> A fix for cp.c would take 2 minutes of coding labor (no, I wouldn't
> really fix it as above) and several hours in the Bug Tracking and
> Approval program. cp's maintainer was uninterested: his program "did
> nothing wrong."

I have to agree with cp's maintainer. I don't see how you can call (3)
or (4) a "bug-like feature", much less a bug. The read system call has
never had any alignment restriction on the buffer. The driver was at
fault, as Scott pointed out. If it is supposed to be a general purpose
driver, it needs to work with any provided buffer. (If the driver is
only intended to work with specific clients, such as a file-system
driver, it might be reasonable for it to return I/O error in this case,
making it the user's fault for using the driver inappropriately.)

In a similar situation, I would use dd instead of cp. I don't know if
that would help in this case, though. I wonder if dd worries about
buffer alignment...

Philip

Ike Naar

unread,
Feb 24, 2012, 4:02:29 AM2/24/12
to
On 2012-02-24, io_x <a...@b.c.invalid> wrote:
> "James Dow Allen" <gm...@jamesdowallen.nospam> ha scritto nel messaggio
> news:XnsA0029CCBE7C...@178.63.61.175...
>> cp.c could be fixed with, for example (:-) )
>> char xbuffer[512+2];
>
> i would write something as:
> double dbuffer[512/sizeof(double)];
> /* suppose sizeof(double)=2^n < 512
> and double aligned >= 4chars
> if one know that double has to be 64bits for standard
> should be ok for me
> */
> char *buffer;
> buffer=(char*) dbuffer;
>
>> #define buffer (xbuffer + (2&(int)xbuffer))

Or use malloc to allocate the buffer (the return value
of malloc is properly aligned for any type).

But it seems the wrong approach to "fix" cp.c to work around the
quirks of a device driver. What if another device driver is installed
that requires 512-byte alignment? Fix cp.c again? What if cat or dd
is used instead of cp? Fix cat.c and dd.c as well?

James Dow Allen

unread,
Feb 24, 2012, 4:04:34 AM2/24/12
to
On Feb 24, 2:51 pm, Philip Lantz <p...@canterey.us> wrote:
> I have to agree with cp's maintainer. I don't see how you can call (3)
> or (4) a "bug-like feature", much less a bug.

I agree with most of the comments posted in response to
my "amusing true story." I think that for cc to enforce
4-byte alignment on large buffers with "round sizes" might
be a slight performance boost independent of any driver
bug, but I might be reluctant to make such a change due to
paranoia about unforeseen consequences.

And I agree that "bug-like feature" was a very poor
phrasing. I wanted a better phrasing, but didn't
spend more than 2 seconds trying to think of one.

And I might agree that "'cp' did nothing wrong", but for
cp's maintainer to refuse to make this simple change seems
inexplicable(*). Even ignoring that it bypasses the bug,
an aligned buffer is going to get better performance.
The mmap() usage was a recent change, so the potentially
misaligned
char buffer[512];
had presumably been used for all files previously.
(My memory is fuzzy. Buffer-size *might* have been some
other power-of-two, e.g. 4096.) A misaligned buffer
is going to give poorer performance than an aligned buffer
even if the kernel is just doing a memcpy()-type operation
from its own aligned buffer.

Efficiencies one doesn't bother with normally *should*
be of concern when writing a standard utility like 'cp.'

(* - The company needed paperwork and approvals for all
changes to existing programs; this may have affected
willingness to change.)

> In a similar situation, I would use dd instead of cp. I don't know if
> that would help in this case, though. I wonder if dd worries about
> buffer alignment...

IIRC, 'dd' (unlike 'cp' and 'cat') did not use mmap() in any
case, but otherwise I don't recall its coding: Its behavior
was irrelevant to me. Please note that I didn't "need"
cp to examine disk labels. :-) Instead I thought the bug
should be circumvented before a customer, whether doing
something silly or not, found it.

James

Shao Miller

unread,
Feb 25, 2012, 2:40:10 AM2/25/12
to
Not just an idiom. C99's 6.5.3.4p6, though an example, doesn't say
"sometimes" anywhere.

Shao Miller

unread,
Feb 25, 2012, 5:22:02 AM2/25/12
to
I just saw a related question in another C-devoted forum, recently. It
was slightly different: "How do I know that '(char *) &bar == (char *)
bar' ?"

Well in C99's 6.5.9, paragraphs 6 and 7 might help.

P6 suggests that an object can have a sub-object at its beginning. It
would seem odd to consider the first element of an array as not
constituting the sub-object at the beginning of an array.

P7 suggests that an object that's not an element of an array be treated
the same as an array with one element, which suggests that at least
'type[1]' has no initial padding. It'd seem odd if a greater count of
elements granted initial padding.

Then there's 'calloc'...

void * ptr = calloc(42, sizeof (int));
int * ip = ptr;
int (* ap)[42] = ptr;

It'd seem odd if 'calloc' had to allocate extra memory just in case you
might access the memory via '*ap' instead of 'ip'. It'd seem to
complicate alignment requirements.

Tim Rentsch

unread,
Mar 8, 2012, 4:14:41 PM3/8/12
to
FWIW, I raised exactly this question in 2005 in comp.std.c. The
thread subject was 'sizeof(T[N]) == (N) * sizeof(T)?', if anyone
is interested.

Tim Rentsch

unread,
Mar 8, 2012, 4:19:42 PM3/8/12
to
If you read the normative text in 6.5.9 p6 (the footnoted paragraph)
in conjunction with the footnote, I think you'll agree that the
two together preclude the possibility of any trailing padding.

Ben Bacarisse

unread,
Mar 8, 2012, 5:25:03 PM3/8/12
to
I'm not getting it. Can you say more?

In my head, I have this picture where a 3-element int array is padded to
be the size of a 4-element one:

int A[2][3], *p1 = A[0] + 3, *p2 = A[1];

+----+----+----+----+----+----+----+----+
A: | | | |XXXX| | | |XXXX|
+----+----+----+----+----+----+----+----+
^ ^
p1 p2

6.5.9 p6 says that p1 and p2 don't compare equal but I don't see why
they must. Presumably this is a case where the "different array" of
6.5.9 p6 does *not* "happen to follow" the first. The footnote gives
permission for p1 and p2 to be equal but, unless I'm misreading it, I
don't see that it requires it.

--
Ben.

Keith Thompson

unread,
Mar 8, 2012, 5:26:04 PM3/8/12
to
Tim Rentsch <t...@alumni.caltech.edu> writes:
> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
[...]
>> For me, no. If the supposed padding is part of the array (like it is
>> with a struct) the arrays are still adjacent.
>
> If you read the normative text in 6.5.9 p6 (the footnoted paragraph)
> in conjunction with the footnote, I think you'll agree that the
> two together preclude the possibility of any trailing padding.

I don't think so.

Here's the paragraph from N1570:

Two pointers compare equal if and only if both are null pointers,
both are pointers to the same object (including a pointer to an
object and a subobject at its beginning) or function, both are
pointers to one past the last element of the same array object,
or one is a pointer to one past the end of one array object and
the other is a pointer to the start of a different array object
that happens to immediately follow the first array object in
the address space.

And here's the footnote:

Two objects may be adjacent in memory because they are adjacent
elements of a larger array or adjacent members of a structure
with no padding between them, or because the implementation
chose to place them so, even though they are unrelated. If prior
invalid pointer operations (such as accesses outside array
bounds) produced undefined behavior, subsequent comparisons
also produce undefined behavior.

The footnote describes circumstances in which two objects *may
be* adjacent in memory. I don't believe it implies that adjacent
elements of a larger array *must be* adjacent in memory.

I think the intent is that consecutive array elements must be
adjacent in memory, but I don't think this footnote is enough to
prove that intent.

Tim Rentsch

unread,
Mar 9, 2012, 5:00:05 PM3/9/12
to
I wouldn't call it intent; more like unconscious assumption.

Tim Rentsch

unread,
Mar 9, 2012, 5:08:55 PM3/9/12
to
My point was about the parallel constructions in p6 (the text of
which Keith Thompson courteously provided in his response). In
one case there is a reference to "one past the last element of an
array object", and in the other a reference to "one past the end
of one array object". Because of the phrasing I think it shows
an unconscious assumption that these two are synonymous: one
past the last element of an array is the same as one past the
whole array, and therefore that there is no padding. This also
explains why the requirement isn't stated explicitly - because
the assumption was made without conscious thought, it never
occurred to anyone to state it.

Ben Bacarisse

unread,
Mar 9, 2012, 5:58:04 PM3/9/12
to
Tim Rentsch <t...@alumni.caltech.edu> writes:

> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>
>> Tim Rentsch <t...@alumni.caltech.edu> writes:
<snip>
>>> If you read the normative text in 6.5.9 p6 (the footnoted paragraph)
>>> in conjunction with the footnote, I think you'll agree that the
>>> two together preclude the possibility of any trailing padding.
>>
>> I'm not getting it. Can you say more?
<snip>
> My point was about the parallel constructions in p6 (the text of
> which Keith Thompson courteously provided in his response). In
> one case there is a reference to "one past the last element of an
> array object", and in the other a reference to "one past the end
> of one array object". Because of the phrasing I think it shows
> an unconscious assumption that these two are synonymous: one
> past the last element of an array is the same as one past the
> whole array, and therefore that there is no padding. This also
> explains why the requirement isn't stated explicitly - because
> the assumption was made without conscious thought, it never
> occurred to anyone to state it.

Right. I see what you mean now.

--
Ben.

Robert Miles

unread,
Apr 1, 2012, 1:24:18 AM4/1/12
to
On 2/23/2012 1:03 AM, Keith Thompson wrote:
> Ben Bacarisse<ben.u...@bsb.me.uk> writes:
>> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>> Ben Bacarisse<ben.u...@bsb.me.uk> writes:
>>>> I don't think that helps. It does not say that the total number of
>>>> bytes in the array can't be a few more than the minimum required.
>>>
>>> There is:
>>>
>>> »There may be unnamed padding at the end of a
>>> structure or union.« 6.7.2.1p15, ISO/IEC 9899:1999 (E)
>>>
>>> But no such license is given for an array.
>>
>> Yes, as I've already said, I think that silence is the strongest
>> argument. That and the explicit example of dividing the array size by
>> the element size to get the length.
>
> Dividing the array size by the element size to get the length would
> still work if the amount of padding at the end of an array is less than
> the size of an element.

Could this be saying that if padding is placed at the end of the array,
sizeof() must not consider it part of the array?

Robert Miles

Kaz Kylheku

unread,
Apr 1, 2012, 1:57:08 AM4/1/12
to
If it's not in sizeof, it's not part of the type, period.

There may be bytes between objects which are the members of a structure. There
may be space between variables that are located in storage next to each other.

The space after an object A, before object B at the higher address,
is not related to the type of object A. It most likely exists for the
sake of correct or efficient alignment of object B.
0 new messages