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

szieof (an array type)

4 views
Skip to first unread message

David Jones

unread,
Apr 23, 1999, 3:00:00 AM4/23/99
to
Assuming N is an integral constant expression, is
sizeof(T[N])
guaranteed to be the same as
(the mathemetical multiplication)
sizeof(T) * N
? (clearly it must be at least that otherwise there aren't enough bytes
for all the objects).

I can't find anywhere in the standard where this is specified.

I can think of almost plausible reasons why I (as an implementor) might
want
sizeof(char[2])
to be 4.

d...@pobox.com
Work: http://www.harlequin.com/mm/reference/
Play: http://www.pobox.com/~drj/


Francis Glassborow

unread,
Apr 23, 1999, 3:00:00 AM4/23/99
to
In article <01be8d8b$e0990d90$daee58c0@aaron>, David Jones
<d...@pobox.com> writes

>Assuming N is an integral constant expression, is
>sizeof(T[N])
>guaranteed to be the same as
>(the mathemetical multiplication)
>sizeof(T) * N
>? (clearly it must be at least that otherwise there aren't enough bytes
>for all the objects).
>
>I can't find anywhere in the standard where this is specified.

I am sure someone else with more time can pin down the exact place in
the standard, but if sizeof(T[N]) were not the same as sizeof(T) * N the
mechanisms for dynamic arrays would fail drastically.

>
>I can think of almost plausible reasons why I (as an implementor) might
>want
>sizeof(char[2])
>to be 4.
>
>d...@pobox.com
>Work: http://www.harlequin.com/mm/reference/
>Play: http://www.pobox.com/~drj/
>

Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

David Jones

unread,
Apr 23, 1999, 3:00:00 AM4/23/99
to

Francis Glassborow <fra...@robinton.demon.co.uk> wrote in article
<ukKeltAN...@robinton.demon.co.uk>...


> In article <01be8d8b$e0990d90$daee58c0@aaron>, David Jones
> <d...@pobox.com> writes
> >Assuming N is an integral constant expression, is
> >sizeof(T[N])
> >guaranteed to be the same as
> >(the mathemetical multiplication)
> >sizeof(T) * N
> >? (clearly it must be at least that otherwise there aren't enough bytes
> >for all the objects).
> >
> >I can't find anywhere in the standard where this is specified.
>
> I am sure someone else with more time can pin down the exact place in
> the standard, but if sizeof(T[N]) were not the same as sizeof(T) * N the
> mechanisms for dynamic arrays would fail drastically.

Are you sure (of either of those statements)? If all one ever does is
pointer arithmetic then it doesn't matter (because all that still works).
When, in mechanisms for implementing dynamic arrays do you use an array
type?

It only begins to matter if
a) you're a pedant
b) you start assuming that (char *)(&a+1) == (char *)(a+N) where "T a[N];".

But in any case an argument that goes "The standard must say this otherwise
all this code that exists in the world is broken" does not hold any water.
How else do we get DRs? (and wording like "Each constant expression shall
evaluate to a constant that is in the range of representable values for its
type." (after Clive)).

I find such blind faith in the standard faintly amusing. Are you one of
these people that thought printf("%lu", (unsigned long)sizeof(foo)) was a
good thing too?

Nick Maclaren

unread,
Apr 23, 1999, 3:00:00 AM4/23/99
to
In article <01be8d9e$d883d460$daee58c0@aaron>,

David Jones <d...@pobox.com> wrote:
>
>
>Francis Glassborow <fra...@robinton.demon.co.uk> wrote in article
><ukKeltAN...@robinton.demon.co.uk>...
>> In article <01be8d8b$e0990d90$daee58c0@aaron>, David Jones
>> <d...@pobox.com> writes
>> >Assuming N is an integral constant expression, is
>> >sizeof(T[N])
>> >guaranteed to be the same as
>> >(the mathemetical multiplication)
>> >sizeof(T) * N
>> >? (clearly it must be at least that otherwise there aren't enough bytes
>> >for all the objects).
>> >
>> >I can't find anywhere in the standard where this is specified.
>>
>> I am sure someone else with more time can pin down the exact place in
>> the standard, but if sizeof(T[N]) were not the same as sizeof(T) * N the
>> mechanisms for dynamic arrays would fail drastically.
>
>Are you sure (of either of those statements)? If all one ever does is
>pointer arithmetic then it doesn't matter (because all that still works).
>When, in mechanisms for implementing dynamic arrays do you use an array
>type?
>
>It only begins to matter if
>a) you're a pedant
>b) you start assuming that (char *)(&a+1) == (char *)(a+N) where "T a[N];".

Yes, he is sure. So am I. I raised this point quite a long time back
in the context of C89, asking whether the standard actually REQUIRED
this or merely ASSUMED it, and several people pointed out enough wording
that I accepted that the former is the case. It isn't there explicitly,
and the constraint is scattered over a good many sections, but it is
there and it is required.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679

Jerry Coffin

unread,
Apr 23, 1999, 3:00:00 AM4/23/99
to
In article <01be8d8b$e0990d90$daee58c0@aaron>, d...@pobox.com says...

> Assuming N is an integral constant expression, is
> sizeof(T[N])
> guaranteed to be the same as
> (the mathemetical multiplication)
> sizeof(T) * N
> ? (clearly it must be at least that otherwise there aren't enough bytes
> for all the objects).
>
> I can't find anywhere in the standard where this is specified.

Yes -- ($6.1.2.5) "An array type describes a contiguously allocated,
non-empty set of objects ..."

By contrast, the elements in a struct are "sequentially allocated"
rather than contiguous. IOW, there can be padding between members of
a struct, but not between elements in an array.

It might be arguable that (at least in theory) a compiler could
allocate extra space at the end of an array for some reason. I can't
find anything in the standard saying it couldn't, but any compiler
that made such a requirement would break essentially EVERY program
that uses malloc, so I think it's safe to say that such a thing won't
happen.

Francis Glassborow

unread,
Apr 24, 1999, 3:00:00 AM4/24/99
to
In article <01be8d9e$d883d460$daee58c0@aaron>, David Jones
<d...@pobox.com> writes

>Are you sure (of either of those statements)? If all one ever does is
>pointer arithmetic then it doesn't matter (because all that still works).
>When, in mechanisms for implementing dynamic arrays do you use an array
>type?

sometype * dynamic = malloc(N*sizeof(sometype));

better work. And AFAICS it requires the equality to hold. Well it can
allocate more memory but the relationship has to work the other way for
other cases:

sometype a[100];
then sizeof(a)/sizeof(sometype) better evaluate to 100.

Ken Walter

unread,
Apr 24, 1999, 3:00:00 AM4/24/99
to
On Fri, 23 Apr 1999 23:55:24, jco...@taeus.com (Jerry Coffin) wrote:

>In article <01be8d8b$e0990d90$daee58c0@aaron>, d...@pobox.com says...
>> Assuming N is an integral constant expression, is
>> sizeof(T[N])
>> guaranteed to be the same as
>> (the mathemetical multiplication)
>> sizeof(T) * N

[...]


>It might be arguable that (at least in theory) a compiler could
>allocate extra space at the end of an array for some reason. I can't
>find anything in the standard saying it couldn't, but any compiler
>that made such a requirement would break essentially EVERY program
>that uses malloc, so I think it's safe to say that such a thing won't
>happen.

The suprise comes with placement new of arrays.
There must (in most implementations) be extra space added
for the count N, but there is no way to determine what that is
except by experiment.

Ken Walter

Remove .zamboni to reply
All the above is hearsay and the opinion of no one in particular

Francis Glassborow

unread,
Apr 24, 1999, 3:00:00 AM4/24/99
to
In article <eDcSHHgdulIC-p...@zamboni.stiscan.com>, Ken
Walter <icedance...@ibm.zamboni.net> writes

>The suprise comes with placement new of arrays.
>There must (in most implementations) be extra space added
>for the count N, but there is no way to determine what that is
>except by experiment.

Did you check which NG you were posting to? No, I thought not. But
even in C++ the relationship holds until the programmer starts getting
extremely adventurous. (and the sizeof still holds as the extra is not
part of the object as such)

James Kuyper

unread,
Apr 25, 1999, 3:00:00 AM4/25/99
to
Ken Walter wrote:
...

> The suprise comes with placement new of arrays.

This newsgroup is about C, not C++. There's no such thing as 'placement
new' in C.

David Jones

unread,
Apr 26, 1999, 3:00:00 AM4/26/99
to

Francis Glassborow <fra...@robinton.demon.co.uk> wrote in article

<N93GzOA5...@robinton.demon.co.uk>...


> In article <01be8d9e$d883d460$daee58c0@aaron>, David Jones
> <d...@pobox.com> writes
> >Are you sure (of either of those statements)? If all one ever does is
> >pointer arithmetic then it doesn't matter (because all that still
works).
> >When, in mechanisms for implementing dynamic arrays do you use an array
> >type?
>
> sometype * dynamic = malloc(N*sizeof(sometype));

(Nick tells me you are sure; you're both just bating me my not showing me
wording. Ho Hum).

You seem to be assuming that the standard defines a language that you'd
actually want to program in Francis.

Yes, I agree, obviously in any sensible language you'd want to be able to
use malloc to allocate arrays. However, I haven't found anything yet that
allows me to do that. calloc on the other hand... is just the tool for the
job: "allocates space for an array of nmemb objects".

> better work. And AFAICS it requires the equality to hold. Well it can
> allocate more memory but the relationship has to work the other way for
> other cases:
>
> sometype a[100];
> then sizeof(a)/sizeof(sometype) better evaluate to 100.

Well, again yes, I'd want that too. But I haven't found anything that
gives me it.

Douglas A. Gwyn

unread,
Apr 26, 1999, 3:00:00 AM4/26/99
to
David Jones wrote:
> Yes, I agree, obviously in any sensible language you'd want to be
> able to use malloc to allocate arrays. However, I haven't found
> anything yet that allows me to do that.

What's stopping you? It is clear that malloc returns properly
aligned storage, and the required amount is easily computable
since padding is included in the size of the array element.
If you convert the pointer returned by malloc to a pointer to
the element type, you can use it to access the elements as in
an array object.

Paul D. Smith

unread,
Apr 26, 1999, 3:00:00 AM4/26/99
to
%% "David Jones" <d...@pobox.com> writes:

>> sometype a[100];
>> then sizeof(a)/sizeof(sometype) better evaluate to 100.

dj> Well, again yes, I'd want that too. But I haven't found anything
dj> that gives me it.

???

Section 3.3.3.4 of ANSI C89 (sorry, don't have the ISO version handy)
specifically guarantees that. It even uses almost that same example.

--
-------------------------------------------------------------------------------
Paul D. Smith <psm...@baynetworks.com> Network Management Development
"Please remain calm...I may be mad, but I am a professional." --Mad Scientist
-------------------------------------------------------------------------------
These are my opinions---Nortel Networks takes no responsibility for them.

David R Tribble

unread,
Apr 26, 1999, 3:00:00 AM4/26/99
to
David Jones wrote:
> Yes, I agree, obviously in any sensible language you'd want to be able
> to use malloc to allocate arrays. However, I haven't found anything
> yet that allows me to do that. calloc on the other hand... is just
> the tool for the job: "allocates space for an array of nmemb objects".

Surely you realize that calloc(n,m) is exactly equivalent to
malloc(n*m)?

-- David R. Tribble, dtri...@technologist.com --

Douglas A. Gwyn

unread,
Apr 26, 1999, 3:00:00 AM4/26/99
to
David R Tribble wrote:
> Surely you realize that calloc(n,m) is exactly equivalent to
> malloc(n*m)?

Well, no, it also fills the storage with zero-bytes.
(Also, n*m might overflow a size_t. Not that one can get
that much storage from the heap, but calloc(n,m) still
ought to function okay and return a null pointer.)

Peter Seebach

unread,
Apr 26, 1999, 3:00:00 AM4/26/99
to
In article <3724B3C2...@technologist.com>,

David R Tribble <dtri...@technologist.com> wrote:
>Surely you realize that calloc(n,m) is exactly equivalent to
>malloc(n*m)?

Not necessarily. It may be that calloc(n,m) can get you more space;
it certainly ought to be able to detect some class of overflows, e.g.,
malloc((ULONG_MAX / 2) * 3)
vs
calloc(ULONG_MAX/2, 3)

-s
--
Copyright 1999, All rights reserved. Peter Seebach / se...@plethora.net
C/Unix wizard, Pro-commerce radical, Spam fighter. Boycott Spamazon!
Will work for interesting hardware. http://www.plethora.net/~seebs/
Visit my new ISP <URL:http://www.plethora.net/> --- More Net, Less Spam!

Francis Glassborow

unread,
Apr 26, 1999, 3:00:00 AM4/26/99
to
In article <p5r9p7c...@baynetworks.com>, Paul D. Smith
<psm...@baynetworks.com> writes

>Section 3.3.3.4 of ANSI C89 (sorry, don't have the ISO version handy)
>specifically guarantees that. It even uses almost that same example.

Actually a strict reading of that section does not actually say how the
number of bytes in an array is calculated. Examples are non-normative.
However I can be 100% certain that any compiler (that is not being
deliberately perverse) will deliver what most of us expect.

James Kuyper

unread,
Apr 26, 1999, 3:00:00 AM4/26/99
to
David R Tribble wrote:
>
> David Jones wrote:
> > Yes, I agree, obviously in any sensible language you'd want to be able
> > to use malloc to allocate arrays. However, I haven't found anything
> > yet that allows me to do that. calloc on the other hand... is just
> > the tool for the job: "allocates space for an array of nmemb objects".
>
> Surely you realize that calloc(n,m) is exactly equivalent to
> malloc(n*m)?

Not quite - two differences:
1) (highly debatable) if those who say that an object is allowed to have
a size bigger than SIZE_MAX are right, then calloc() could dynamically
allocate such an object; malloc() can't.

2) (not in the least debatable) calloc() initializes all bits to 0,
malloc() doesn't.

Nick Maclaren

unread,
Apr 27, 1999, 3:00:00 AM4/27/99
to
In article <MYiWqfAq...@robinton.demon.co.uk>,

Francis Glassborow <fran...@robinton.demon.co.uk> wrote:
>In article <p5r9p7c...@baynetworks.com>, Paul D. Smith
><psm...@baynetworks.com> writes
>>Section 3.3.3.4 of ANSI C89 (sorry, don't have the ISO version handy)
>>specifically guarantees that. It even uses almost that same example.
>
>Actually a strict reading of that section does not actually say how the
>number of bytes in an array is calculated. Examples are non-normative.
>However I can be 100% certain that any compiler (that is not being
>deliberately perverse) will deliver what most of us expect.

If I remember correctly, it could be proved that this was required
but, to do so, needed the collation of at least three (and perhaps
five) widely separated sections in the standard.

David Jones

unread,
Apr 27, 1999, 3:00:00 AM4/27/99
to

Douglas A. Gwyn <DAG...@null.net> wrote in article
<3724AA64...@null.net>...


> David Jones wrote:
> > Yes, I agree, obviously in any sensible language you'd want to be
> > able to use malloc to allocate arrays. However, I haven't found
> > anything yet that allows me to do that.
>

> What's stopping you? It is clear that malloc returns properly
> aligned storage, and the required amount is easily computable
> since padding is included in the size of the array element.
> If you convert the pointer returned by malloc to a pointer to
> the element type, you can use it to access the elements as in
> an array object.

Have you been following this Douglas? Please show me where in the standard
it says how to compute the size of an array.

Obviously the size of an array "T a[n];" must be at least n*sizeof(T), but
can there be padding _at the end_ of an array?

Referring to ISO 9899:1990

Subclause 6.3.3.4 The sizeof operator

...

When applied to an operand that has array type, the result is the number
of bytes in the array.

So that doesn't tell me how to compute the size of an array.

7.10.3.1 The calloc function

...

The calloc function allocates space for an array of nmemb objects.

So I can allocate one, but not know how big it is (it does not say that
calloc allocates nmemb*size bytes in particular).

6.3.6 Additive operators

... blah blah blah ...

This tells me that given "T a[n];" then ((char *)a + sizeof(T)*n) == ((char
*)(a+n)). Fine. It does not tell me ((char *)(a+n)) == (char *)(&a+1), ie
it doesn't say here that stepping over all the elements of an array takes
me to the same place as the end of the array. To quote some wording:

the expression (P)+1 points one past the last element of the array object

Note it does _not_ say "the end of the array", no equivalence has yet been
established between "one past the last element of the array object" and
"the end of the array".

Subclause 6.2.2.3 doesn't say anything useful about pointer conversion in
this matter.

Subclause 6.1.2.5 says:

An array type describes a contiguously allocated nonempty set of objects
with a particular memb object type ...

I'm increasingly convinced that the writers of the standard just assumed
that the size of an array was the size of each element multiplied by the
number of elements and forgot to state that.

To state the problem the other way around. In my proposed implementation
I'm going to define sizeof on array type in the following way (so that
arrays with more than one element have an extra byte of padding):

let T be an array with element type E and n elements.

sizeof(T) = n > 1 ? (sizeof(E)*n+1) : sizeof(E)

What in the standard prevents me?

David Jones

unread,
Apr 27, 1999, 3:00:00 AM4/27/99
to

Douglas A. Gwyn <DAG...@null.net> wrote in article

<3724BB96...@null.net>...


> David R Tribble wrote:
> > Surely you realize that calloc(n,m) is exactly equivalent to
> > malloc(n*m)?
>

> Well, no, it also fills the storage with zero-bytes.
> (Also, n*m might overflow a size_t. Not that one can get
> that much storage from the heap, but calloc(n,m) still
> ought to function okay and return a null pointer.)

It ought to oughtn't it? The last one I looked at (Microsoft Visual C
runtime IIRC) didn't (it just blithely did the multiply). *sigh*

Perhaps if there had been a note in the standard, er, I mean in a document
called "guidance for implementing the ISO C standard", to the effect that
calloc's interface meant that overflow on the (implicit) multiplication
could be checked for and handled gracefully then such a check would be more
common.

Nick Maclaren

unread,
Apr 27, 1999, 3:00:00 AM4/27/99
to

In article <01be9097$ce677260$daee58c0@aaron>, "David Jones" <d...@pobox.com> writes:
|>
|> Have you been following this Douglas? Please show me where in the standard
|> it says how to compute the size of an array.
|>
|> Obviously the size of an array "T a[n];" must be at least n*sizeof(T), but
|> can there be padding _at the end_ of an array?
|>
|> Referring to ISO 9899:1990
|>
|> Subclause 6.3.3.4 The sizeof operator
|>
|> When applied to an operand that has array type, the result is the number
|> of bytes in the array.
|>
|> So that doesn't tell me how to compute the size of an array.

Look, I told you that it wasn't pretty, but it was there. Here is
a selection of quotes from the C9X (C89 is similar) - if you work
through the possibilities, you will find out that it IS specified.
I have no idea why there is nothing in what I should have thought
of as the obvious place (6.7.5.2 Array declarators), but that is
the way that it is.

6.2.5 Types

-- An array type describes a contiguously allocated
nonempty set of objects with a particular member object
type, called the element type.36) Array types are
characterized by their element type and by the number
of elements in the array. An array type is said to be
derived from its element type, and if its element type
is T, the array type is sometimes called ``array of
T''. The construction of an array type from an element
type is called ``array type derivation''.

6.3.2.1 Lvalues, arrays, and function designators |

[#3] Except when it is the operand of the sizeof operator or
the unary & operator, or is a string literal used to
initialize an array, an expression that has type ``array of
type'' is converted to an expression with type ``pointer to
type'' that points to the initial element of the array
object and is not an lvalue. If the array object has
register storage class, the behavior is undefined.

6.5.2.1 Array subscripting

Constraints

[#1] One of the expressions shall have type ``pointer to
object type'', the other expression shall have integer type,
and the result has type ``type''.

Semantics

[#2] A postfix expression followed by an expression in
square brackets [] is a subscripted designation of an
element of an array object. The definition of the subscript
operator [] is that E1[E2] is identical to (*((E1)+(E2))).
Because of the conversion rules that apply to the binary +
operator, if E1 is an array object (equivalently, a pointer
to the initial element of an array object) and E2 is an
integer, E1[E2] designates the E2-th element of E1 (counting
from zero).

6.5.6 Additive operators

[#7] For the purposes of these operators, a pointer to a
nonarray object behaves the same as a pointer to the first
element of an array of length one with the type of the
object as its element type.

[#8] When an expression that has integer type is added to or
subtracted from a pointer, the result has the type of the
pointer operand. If the pointer operand points to an
element of an array object, and the array is large enough,
the result points to an element offset from the original
element such that the difference of the subscripts of the
resulting and original array elements equals the integer
expression. In other words, if the expression P points to
the i-th element of an array object, the expressions (P)+N
(equivalently, N+(P)) and (P)-N (where N has the value n)
point to, respectively, the i+n-th and i-n-th elements of
the array object, provided they exist.

Clive D.W. Feather

unread,
Apr 28, 1999, 3:00:00 AM4/28/99
to
In article <01be9097$ce677260$daee58c0@aaron>, David Jones
<d...@pobox.com> writes
>Have you been following this Douglas? Please show me where in the standard
>it says how to compute the size of an array.
>
>Obviously the size of an array "T a[n];" must be at least n*sizeof(T), but
>can there be padding _at the end_ of an array?

I would say no, because wherever the Standard allows padding it
explicitly says so, and it doesn't say it for arrays.

I am sure that - were a DR to be filed - our response would be either
that it is clear or to adjust the wording to make it clear.

>To quote some wording:
>
> the expression (P)+1 points one past the last element of the array object
>
>Note it does _not_ say "the end of the array", no equivalence has yet been
>established between "one past the last element of the array object" and
>"the end of the array".

Don't read anything into that - it's simply that in this context we're
more interested in members than in the array as a whole.

--
Clive D.W. Feather | Internet Expert | Work: <cl...@demon.net>
Tel: +44 181 371 1138 | Demon Internet Ltd. | Home: <cl...@davros.org>
Fax: +44 181 371 1037 | | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address

John R. Mashey

unread,
Apr 28, 1999, 3:00:00 AM4/28/99
to
In article <WvWqw3Nm$tJ3...@romana.davros.org>, "Clive D.W. Feather" <cl...@on-the-train.demon.co.uk> writes:

|> >Obviously the size of an array "T a[n];" must be at least n*sizeof(T), but
|> >can there be padding _at the end_ of an array?

This reminds me: while it is clearly too late for a new feature,
can anyone on the Committee say if there's been any discussion of the
following sort of thing, and if not, people might start thinking of it
for the next time.

Here is the problem: many assemblers support a .origin or equivalent
directive that can be used to align a data item/structure onto
power-of-2 boundaries larger than data items actually found in C,
i.e., of special relevance would be cache-line-sizes (32, 64, 128 typical),
or page sizes. Codes exist that already work fairly hard to control
the alignment of structures, arrays, COMMON blocks, and sometimes
heavily-contended locks (which are good things to have in separate
cache lines).

but the reasons for doing this are inevitably going to get much more important (later).

Perhaps something like (don't care much about the syntax)
#define LINESIZE 64
....
aligned(LINESIZE) struct x { ...} xx;

should, for sure, align xx on a multiple of LINESIZE ... and probably pad its size to a multiple of LINESIZE so that arrays of x's all started on the
same alignment. I.e., this is similar to the effect currently
obtained by declaring as the first data item in x, a data time with the
most restrictive alignment requirements (typically 8 bytes, or maybe
16 bytes if an implementation supports a 128-bit aligned long double).
I.e., this is the same sort of mechanism, all that's happened is that
the existing alignments of 1, 2, 4 (8, 16) get augmented by 32, 64, 128, etc.

As to why one cares, it is sad, but true that the increasing gap between
CPU speed and DRAM is increasing the relative cost of cache misses,
and we're headed towards having to think more about data placements.
In 1985, you could do 1-2 instructions in the time of a memory access.
In 2001, this is likely to be approaching 1000 (peak) instructions
in the time of a cache miss (i.e., imagine 1ns CPU cycle, 4-6 issues/cycle,
and 150ns realistic memory time = 600-900 instructions.)

It may be very useful to make sure that a struct doesn't cross more
line-size boundaries than it needs to.

On the one hand, it is disturbing to think that an implementation thing
like line-size might start getting embedded into more user code.
On the other hand, this is not a fundamentally new mechanism.
On the third hand "the gripping hand"), C's ability to provide
efficient code is going to be udner stress fro mteh CPU-DRAM gap,
so we need to start thinking about it.


--
-john mashey DISCLAIMER: <generic disclaimer: I speak for me only...>
EMAIL: ma...@sgi.com DDD: 650-933-3090 FAX: 650-933-4392
USPS: Silicon Graphics/Cray Research 40U-005,
2011 N. Shoreline Blvd, Mountain View, CA 94043-1389

Nick Maclaren

unread,
Apr 28, 1999, 3:00:00 AM4/28/99
to
In article <7g7ejh$idf$1...@murrow.corp.sgi.com>,

John R. Mashey <ma...@mash.engr.sgi.com> wrote:
>In article <WvWqw3Nm$tJ3...@romana.davros.org>, "Clive D.W. Feather" <cl...@on-the-train.demon.co.uk> writes:
>
>|> >Obviously the size of an array "T a[n];" must be at least n*sizeof(T), but
>|> >can there be padding _at the end_ of an array?
>
>This reminds me: while it is clearly too late for a new feature,
>can anyone on the Committee say if there's been any discussion of the
>following sort of thing, and if not, people might start thinking of it
>for the next time.
>
>Here is the problem: many assemblers support a .origin or equivalent
>directive that can be used to align a data item/structure onto
>power-of-2 boundaries larger than data items actually found in C,
>i.e., of special relevance would be cache-line-sizes (32, 64, 128 typical),
>or page sizes. Codes exist that already work fairly hard to control
>the alignment of structures, arrays, COMMON blocks, and sometimes
>heavily-contended locks (which are good things to have in separate
>cache lines).
>
>but the reasons for doing this are inevitably going to get much more important (later).

I don't know, formally, but it has certainly been brought up in the
context of the MAX_ALIGN debate.

One of the big problems is defining what you mean by alignment in
the first place - the definition in 3.2 makes little sense in terms
of a segmented architecture, and none whatsoever in terms of a
capability one. And what about systems with different kinds of
memory?

I think that it could be done, but am not sure it is a good way to
go, and it certainly isn't trivial. Assemblers are usually system-
specific, which makes the definitions a lot easier.

Peter Curran

unread,
Apr 28, 1999, 3:00:00 AM4/28/99
to
On 28 Apr 1999 16:56:17 GMT, ma...@mash.engr.sgi.com (John R. Mashey)
wrote:

<snip>

Surely this is the kind of thing #pragma, etc., was designed to
address.

--
Peter Curran pcu...@acm.gov (chg gov=>org)

Noone Really

unread,
Apr 28, 1999, 3:00:00 AM4/28/99
to
Nick Maclaren wrote:
> >>Section 3.3.3.4 of ANSI C89 (sorry, don't have the ISO version handy)
> >>specifically guarantees that. It even uses almost that same example.
> >
> >Actually a strict reading of that section does not actually say how the
> >number of bytes in an array is calculated. Examples are non-normative.
> >However I can be 100% certain that any compiler (that is not being
> >deliberately perverse) will deliver what most of us expect.
>
> If I remember correctly, it could be proved that this was required
> but, to do so, needed the collation of at least three (and perhaps
> five) widely separated sections in the standard.

Can anyone remember the argument. I do not recall having seen the
argument ever.
---


Noone Really

unread,
Apr 29, 1999, 3:00:00 AM4/29/99
to
Nick Maclaren wrote:
> Look, I told you that it wasn't pretty, but it was there. Here is
> a selection of quotes from the C9X (C89 is similar) - if you work
> through the possibilities, you will find out that it IS specified.
> I have no idea why there is nothing in what I should have thought
> of as the obvious place (6.7.5.2 Array declarators), but that is
> the way that it is.

I can't follow the logic. Summarizing you quotes

6.2.5 describes array types as `contiguosuly allocated nonempty set of
objects with a particular member object type' and are `characterized by
their element type and by the number of elements in the array'. I do
not know how this disallows trailing padding: the first quoted (here)
phrase is vry similar to that in `a structure type describes a
sequentially allocated nonempty set of member objects each of which has
an optionally specified name and possibly distinct type'. As the
latter obviously allows padding, this section alone does not seem to
ruleout padding, except in the middle of the array. Are you reading
something into the second part I quoted? (The `characterized by...'
part?)

6.3.2.1 says that arrays in some circumstances become a pointer to its
first element.

6.5.2.1 defines and constrains E1[E2] as being he E2th element of the
array to whose first element E1 points (if it does so). In general it
defines it in terms of the binary + and unary * operators.

6.5.6 defines this addition to mean that if a pointer is pointing to
some element the resultng pointer points to the element offset by the
integer being added, if `the array is large enough'. It clarifies that
the array is large enough if the appropriate element exists. Are you
reading the `large enough' as a comment on the size of the array? I
find that reading difficult because the whole description is in terms of
elements, and possible padding is not an element of the array.

I would appreciate a short explanation if you have the time.

Incidentally, 6.5.6 [#7] is talking of pointers to nonarray objects,
whereas [#8] is talking about pointers to elements of arrays. What
happens when a pointer points to an array object that is not an element
of any array? Implicitly undefined?
---


Nick Maclaren

unread,
Apr 29, 1999, 3:00:00 AM4/29/99
to
In article <3728072E...@earthlink.net>,

Noone Really <nooneat...@earthlink.net> wrote:
>
>I can't follow the logic. Summarizing you quotes
>
>6.2.5 describes array types as `contiguosuly allocated nonempty set of
>objects with a particular member object type' and are `characterized by
>their element type and by the number of elements in the array'. I do
>not know how this disallows trailing padding: ...

No, it doesn't. But it does disallow embedded padding.

>6.3.2.1 says that arrays in some circumstances become a pointer to its
>first element.

No. It defines that arrays are semantically ALWAYS pointers to
their first elements, though perhaps with a different size.
Syntactically, they sometimes aren't.

>6.5.2.1 defines and constrains E1[E2] as being he E2th element of the
>array to whose first element E1 points (if it does so). In general it
>defines it in terms of the binary + and unary * operators.

The consequence is that it establishes an equivalence between pointer
addition and array subscription. This is a crucial key.

>6.5.6 defines this addition to mean that if a pointer is pointing to
>some element the resultng pointer points to the element offset by the
>integer being added, if `the array is large enough'. It clarifies that
>the array is large enough if the appropriate element exists. Are you
>reading the `large enough' as a comment on the size of the array? I
>find that reading difficult because the whole description is in terms of
>elements, and possible padding is not an element of the array.

I realise that I snipped a little too much. Here is the extra
information:

... Moreover, if the expression P points either to
an element of an array object or one past the last element
of an array object, and the expression Q points to the last
element of the same array object, the expression ((Q)+1)-(P)
has the same value as ((Q)-(P))+1 and as -((P)-((Q)+1)), and
has the value zero if the expression P points one past the
last element of the array object, even though the expression
(Q)+1 does not point to an element of the array object.85)

This forbids trailing padding, when interpreted in the light of the
other sections I refer to.

>I would appreciate a short explanation if you have the time.

No problem. Incidentally, the previous discussion that I referred
to may have been on the reflector. The point is that this array
property IS required, but is well hidden and has to be deduced.
Some other "well-known" properties of the language turn out not to
be specified at all.

Clive D.W. Feather

unread,
Apr 29, 1999, 3:00:00 AM4/29/99
to
In article <3728072E...@earthlink.net>, Noone Really
<nooneat...@earthlink.net> writes

>6.2.5 describes array types as `contiguosuly allocated nonempty set of
>objects with a particular member object type' and are `characterized by
>their element type and by the number of elements in the array'. I do
>not know how this disallows trailing padding:

Because it does not allow it.

>the first quoted (here)
>phrase is vry similar to that in `a structure type describes a
>sequentially allocated nonempty set of member objects each of which has
>an optionally specified name and possibly distinct type'. As the
>latter obviously allows padding,

Not "obviously". The padding is allowed by 6.7.2.1:

There may be unnamed padding within a structure object, but not at
its beginning.
[...]
There may be unnamed padding at the end of a structure or union.

There is no equivalent wording for unions.

See also the wording of sizeof.


Another possible approach would go something like this, though I haven't
worked on the details. Suppose that (int [5]) had trailing padding. Then
in:
int v [3][5];
the objects v[1][4] and v[2][0] would not be adjacent in memory. I have
a feeling it ought to be possible to do something with this to prove the
point.

>Incidentally, 6.5.6 [#7] is talking of pointers to nonarray objects,
>whereas [#8] is talking about pointers to elements of arrays. What

>happens when a pointer points to an array object that is not an element
>of any array? Implicitly undefined?

Huh ? What #7 says is that any pointer to something that is *not* part
of an array is to be treated as if it *is* part of an array of size 1.

Noone Really

unread,
Apr 29, 1999, 3:00:00 AM4/29/99
to
Clive D.W. Feather wrote:

[clipped opinion that unless padding is explicitly allowed, it is
disallowed.]

I agree that is a possible reading of the standard.

However, in C89 there was possibly no wording explicitly allowing object
representations to have holes in it, and yet the responses to DR 69
decided not to change the wording of the standard! So, obviously the
implication was that the C89 committee felt that absence of any mention
of unused parts in storage is not sufficient to conclude that the
standard forbids them.

That is the reason why I did not use your argument.

> Another possible approach would go something like this, though I haven't
> worked on the details. Suppose that (int [5]) had trailing padding. Then
> in:
> int v [3][5];
> the objects v[1][4] and v[2][0] would not be adjacent in memory. I have
> a feeling it ought to be possible to do something with this to prove the
> point.
>

I tried.

> >Incidentally, 6.5.6 [#7] is talking of pointers to nonarray objects,
> >whereas [#8] is talking about pointers to elements of arrays. What
> >happens when a pointer points to an array object that is not an element
> >of any array? Implicitly undefined?
>
> Huh ? What #7 says is that any pointer to something that is *not* part
> of an array is to be treated as if it *is* part of an array of size 1.

I was going by Mr. Maclaren's wording (which agree with that in C89).
#7 does not talk about pointer to something that is *not* a part of an
array object, it talks about `pointer to a nonarray object'. Thus,
after char a[5]; &a is a pointer to an array object, an hence is not a
pointer to a nonarray object and hence #7 does not apply. But at the
same time, it is not a pointer to an element of an array, and hence #8
does not apply. So, what gives &a+0 any meaning?

Obviously the problem is with the locution `nonarray object'. Is that
defined anywhere? Or has the wording changed?
---


Larry Jones

unread,
Apr 29, 1999, 3:00:00 AM4/29/99
to
Noone Really wrote:
>
> Obviously the problem is with the locution `nonarray object'. Is that
> defined anywhere? Or has the wording changed?

There's no explicit definition; it was intended to be interpreted as
``object which is not an element of an array'', but I can certainly
understand your confusion. I'll change it if I can.

-Larry Jones

It's going to be a long year. -- Calvin

Clive D.W. Feather

unread,
Apr 30, 1999, 3:00:00 AM4/30/99
to
In article <372879FA...@sdrc.com>, Larry Jones
<larry...@sdrc.com> writes

>I'll change it if I can.

Given that I have the FDIS in my hand, when will you be able to ?

Clive D.W. Feather

unread,
Apr 30, 1999, 3:00:00 AM4/30/99
to
In article <37281EB1...@earthlink.net>, Noone Really
<nooneat...@earthlink.net> writes

>[clipped opinion that unless padding is explicitly allowed, it is
>disallowed.]
>
>I agree that is a possible reading of the standard.
>
>However, in C89 there was possibly no wording explicitly allowing object
>representations to have holes in it, and yet the responses to DR 69
>decided not to change the wording of the standard!

True. But there was nowhere that explicitly talked about it either. In
the case of padding bytes they are explicitly mentioned with structures
and unions, leading me to believe that they would also have been if
allowed in arrays.

I'll accept that it wouldn't hurt to clarify the wording.

Larry Jones

unread,
May 4, 1999, 3:00:00 AM5/4/99
to
Clive D.W. Feather wrote:
>
> In article <372879FA...@sdrc.com>, Larry Jones
> <larry...@sdrc.com> writes
> >I'll change it if I can.
>
> Given that I have the FDIS in my hand, when will you be able to ?

My understanding is that I am permitted to make *purely* editorial
changes to the document before it is published. This license is
usually used to correct typos; I don't know if this correction will
be allowed or not.

-Larry Jones

I've changed my mind, Hobbes. People are scum. -- Calvin

Antoine Leca

unread,
May 6, 1999, 3:00:00 AM5/6/99
to
Larry Jones wrote:
>
> Clive D.W. Feather wrote:
> >
> > In article <372879FA...@sdrc.com>, Larry Jones
> > <larry...@sdrc.com> writes
> > >I'll change it if I can.
> >
> > Given that I have the FDIS in my hand, when will you be able to ?
>
> My understanding is that I am permitted to make *purely* editorial
> changes to the document before it is published. This license is
> usually used to correct typos; I don't know if this correction will
> be allowed or not.

(I doubt such a correction is allowed, but I am certainly no expert).

Additionally, the committee might also issue a second FDIS.

C9X will then become C2K, but as some are loudly vociferating that the
standard should not pass as such, this is ever possible...


Another possibility is that Larry is trying to say he is volunteer
for editor to the C0X standard. Thanks, Larry ! ;-)


Antoine

0 new messages