Topic: Question about sizeof in C/C++.
Author: jimad@microsoft.com (Jim Adcock)
Date: 24 Dec 92 00:15:40 GMT Raw View
jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
| Given
|
| struct Something* ps;
| unsigned k;
|
| do the C or C++ standards guarantee that
|
| &ps[k] == ((char*) ps) + k * sizeof(struct Something)
No. The relationship holds only if k is chosen such that k is greater
than or equal to zero [true since k unsigned], and k is less than or equal
to the number of elements in the array pointed-to by ps, assuming ps
points at a valid array of type Something, and in C++ assuming that
that operator& isn't user-defined on struct [class] Something....
Did I miss anything?
Author: diamond@jit533.jit.dec.com (Norman Diamond)
Date: Thu, 24 Dec 1992 02:06:45 GMT Raw View
In article <cuX5VB1w164w@amfent.Gwinnett.COM> amf@amfent.Gwinnett.COM (Andy Feibus) writes:
>diamond@jit345.bad.jit.dec.com (Norman Diamond) writes:
>>In article <wwJXVB3w164w@amfent.Gwinnett.COM> amf@amfent.Gwinnett.COM (Andy F
>>>jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
>>>>do the C or C++ standards guarantee that &ps[k] == [...]
>>>the answer is... no.
>>He was asking about the standards [...] the answer is... yes.
>he also asked:
>>>>is it portable?
>And that was the question I answered.
>>>Different compilers see &ps[k] differently; use parentheses to clarify:
>>> &(ps[k]).
>>Even K&R-1 and Stroustrop-1 prohibited seeing this expression differently.
>That's nice in theory, but I've found at least one UNIX-based compiler
>that interprets it differently. Since his question was about portability,
OK, you found at least one UNIX-based compiler for a non-C language.
I've found various compilers with various bugs too. If you assert that
portability means porting to broken compilers, then there is no such thing
as a portable program. Zero. Zilch. I think the original poster was
asking about portability among standard conforming implementations. In
fact, even among pre-standard implementations of the C and C++ languages,
portability was there.
--
Norman Diamond diamond@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"It's been a lovely recession."
Author: jamesc@swapsdev.state.state.COM.AU (James Cribb)
Date: 1 Jan 93 02:19:19 GMT Raw View
jimad@microsoft.com (Jim Adcock) writes:
>jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
>| Given
>| struct Something* ps;
>| unsigned k;
>| do the C or C++ standards guarantee that
>| &ps[k] == ((char*) ps) + k * sizeof(struct Something)
>
>No. The relationship holds only if ... k is less than or equal
>to the number of elements in the array pointed-to by ps
My code meets those conditions, but just out of interest,
if k is too big, what could cause an inequality (of the addresses)?
j.c
Author: bill@twwells.com (T. William Wells)
Date: 1 Jan 93 13:54:52 GMT Raw View
In article <jamesc.725854759@bart> jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
: jimad@microsoft.com (Jim Adcock) writes:
: >jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
: >| Given
: >| struct Something* ps;
: >| unsigned k;
: >| do the C or C++ standards guarantee that
: >| &ps[k] == ((char*) ps) + k * sizeof(struct Something)
: >
: >No. The relationship holds only if ... k is less than or equal
: >to the number of elements in the array pointed-to by ps
:
: My code meets those conditions, but just out of interest,
: if k is too big, what could cause an inequality (of the addresses)?
In the compiler I've written, if an object is known to be less
than 64K bytes, its index arithmetic is done with 16 bits but all
pointer arithmetic is done with 32 bits. So, if sizeof(*ps) * k
is over 64K, the pointer arithmetic will create a different
result from the index arithmetic.
(Well OK, for this particular example, the compiler is actually
smart enough to see the equivalence between the index expression
and the pointer addition and so the equality would hold. But if
the (char*)ps weren't detectable as an object pointer, they
wouldn't be equal.)
---
Bill { rutgers | decwrl | telesci }!twwells!bill
bill@twwells.com
Author: scjones@thor.sdrc.com (Larry Jones)
Date: 17 Dec 92 22:30:23 GMT Raw View
In article <wwJXVB3w164w@amfent.Gwinnett.COM>, amf@amfent.Gwinnett.COM (Andy Feibus) writes:
> Different compilers see &ps[k]
> differently; use parentheses to clarify: &(ps[k]).
Anything that sees &ps[k] as being different than &(ps[k]) is
*NOT* a C compiler.
----
Larry Jones, SDRC, 2000 Eastman Dr., Milford, OH 45150-2789 513-576-2070
larry.jones@sdrc.com or ...uunet!sdrc!larry.jones
I think we need to change the rules. -- Calvin
Author: diamond@jit345.bad.jit.dec.com (Norman Diamond)
Date: Fri, 18 Dec 1992 02:16:10 GMT Raw View
In article <wwJXVB3w164w@amfent.Gwinnett.COM> amf@amfent.Gwinnett.COM (Andy Feibus) writes:
>jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
>> Given
>> struct Something* ps;
>> unsigned k;
>> do the C or C++ standards guarantee that
>> &ps[k] == ((char*) ps) + k * sizeof(struct Something)
>Assuming that you [cm]alloc enough memory for ps to support accessing the
>k'th element of it, the answer is... no.
He was asking about the standards, for which (under the condition you state)
the answer is... yes.
>Different compilers see &ps[k] differently; use parentheses to clarify:
> &(ps[k]).
Even K&R-1 and Stroustrop-1 prohibited seeing this expression differently.
Parenthesization is nice for human readers so that we don't have to look it
up all the time, but not necessary for C or C++ compilers.
--
Norman Diamond diamond@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"It's been a lovely recession."
Author: diamond@jit533.jit.dec.com (Norman Diamond)
Date: Mon, 21 Dec 1992 10:38:23 GMT Raw View
In article <jamesc.724907666@bart> jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
>Suppose a single struct Something needed 7 bytes of memory. For word
>alignment, these might need to start on, say, 4-byte boundaries.
>Do the standards guarantee that sizeof(struct Something) will always be
>8 rather than 7?
Yes. ANSI's original C standard section 3.5.2.1, page 62 lines 2 to 3:
"Each non-bit-field member of a structure or union object is aligned in an
implementation-defined manner appropriate to its type." Lines 13 to 14:
"There may also be unnamed padding at the end of a structure or union, as
necessary to achieve the appropriate alignment were the structure or union
to be an element of an array."
If it is appropriate for a member type to be aligned on a 4-byte boundary,
then the implementation-defined manner will result in such alignment,
including if necessary a padding byte at the end of the structure.
--
Norman Diamond diamond@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"It's been a lovely recession."
Author: steve@taumet.com (Steve Clamage)
Date: Mon, 21 Dec 1992 16:58:58 GMT Raw View
jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
>Suppose a single struct Something needed 7 bytes of memory. For word
>alignment, these might need to start on, say, 4-byte boundaries.
>E.g. (assume 4-byte floats),
> struct Something
> {
> float x;
> char s[3];
> };
>Do the standards guarantee that sizeof(struct Something) will always be
>8 rather than 7?
The C Standard (there isn't a C++ Standard yet) guarantees:
- sizeof will return the amount of space reserved by the struct when it
is a member of an array;
- each sub-object will be properly aligned;
- there will be no unused space (padding) at the start of the struct.
There may be padding between members or at the end of the struct. The
size of the struct might be larger or smaller than the sum of the
sizeof's of its members. (The compiler might pack struct members more
or less tightly than objects in an array.)
So if floats must start on a 4-byte boundary and sizeof(float)==4,
then sizeof(struct Something) cannot be 7. It must be some value
greater than 7 which is a multiple of 4. The most likely candidate
is 8, but that is not guaranteed by the Standard.
For the case of C++ structs which are also legal C structs, the rules
should be the same in the eventual C++ Standard. That is, the intent
(at the moment) is that a C struct should have the same size and memory
layout when compiled by a compatible C++ compiler.
--
Steve Clamage, TauMetric Corp, steve@taumet.com
Author: amf@amfent.Gwinnett.COM (Andy Feibus)
Date: Mon, 21 Dec 92 08:54:59 EST Raw View
Resending this, since my upstream feed seems to be having problems....
diamond@jit345.bad.jit.dec.com (Norman Diamond) writes:
> In article <wwJXVB3w164w@amfent.Gwinnett.COM> amf@amfent.Gwinnett.COM (Andy F
> >jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
> >> Given
> >> struct Something* ps;
> >> unsigned k;
> >> do the C or C++ standards guarantee that
> >> &ps[k] == ((char*) ps) + k * sizeof(struct Something)
> >Assuming that you [cm]alloc enough memory for ps to support accessing the
> >k'th element of it, the answer is... no.
> He was asking about the standards, for which (under the condition you state)
> the answer is... yes.
Thanks for quoting me out of context, but he also asked:
I'm asking because I have C++ code that relies on this.
It works on Suns but is it portable?
And that was the question I answered.
> >Different compilers see &ps[k] differently; use parentheses to clarify:
> > &(ps[k]).
> Even K&R-1 and Stroustrop-1 prohibited seeing this expression differently.
That's nice in theory, but I've found at least one UNIX-based compiler
that interprets it differently. Since his question was about
portability, I told him what to do to make sure it worked on
whatever compiler he chose. Of course it's not standard, but
complying with the standard and being portable can sometimes be
two very different animals.
-- Andy.
andyfe@utoday.com
Author: amf@amfent.Gwinnett.COM (Andy Feibus)
Date: 17 Dec 92 14:10:55 GMT Raw View
jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
> Given
>
> struct Something* ps;
> unsigned k;
>
> do the C or C++ standards guarantee that
>
> &ps[k] == ((char*) ps) + k * sizeof(struct Something)
>
> I'm asking because I have C++ code that relies on this.
> It works on Suns but is it portable?
Assuming that you [cm]alloc enough memory for ps to support accessing the
k'th element of it, the answer is... no. Different compilers see &ps[k]
differently; use parentheses to clarify: &(ps[k]).
-- Andy.
andyfe@utoday.com