Topic: Where next for C++: Member placement
Author: smeyers@teleport.com (Scott Meyers)
Date: 1997/12/02 Raw View
In article <m3sote3vjh.fsf@gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
| A char cannot have alignment requirements. Indirectly: it can be shown
| that an implementation in which the alignment requirements of T are
| greater than sizeof(T) cannot be conforming. And of course, since
| sizeof( char ) is required to be 1, you must be able to put a char at
| any byte address.
Is this really true? I'd heard that on Crays, each char was 32 bits in
length, though of course it was still the case that sizeof(char) was 1.
Must every conforming implementation be able to put a char at any byte
address? If so, what part of the standard leads to this requirement?
Scott
--
Scott Meyers, Ph.D. Voice: 503/638-6028
C++ Consulting and Training Fax: 503/638-6614
Author of "Effective C++" Email: smeyers@aristeia.com
and "More Effective C++" WWW: http://www.aristeia.com/
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/12/02 Raw View
Scott Meyers wrote:
>
> Is this really true? I'd heard that on Crays, each char was 32 bits in
> length, though of course it was still the case that sizeof(char) was 1.
> Must every conforming implementation be able to put a char at any byte
> address? If so, what part of the standard leads to this requirement?
I would guess that in such an environment "byte" would be defined as 32 bits,
and _everything_ would be a multiple of 32 bits. Accessing files in text mode
would, I suppose, have to convert between the internal 32-bit bytes and the
external 8-bit bytes, which would be a waste of space, but when you're paying a
million bucks for the machine, who cares?
--
Ciao,
Paul
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Alan Stokes <alan@rcp.co.uk>
Date: 1997/12/02 Raw View
Scott Meyers wrote:
>
> In article <m3sote3vjh.fsf@gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
> | And of course, since
> | sizeof( char ) is required to be 1, you must be able to put a char at
> | any byte address.
>
> Is this really true? I'd heard that on Crays, each char was 32 bits in
> length, though of course it was still the case that sizeof(char) was 1.
Yes. And on such a machine a byte is 32 bits (see the definition of
sizeof - it returns the number of bytes in an object, and returns 1 for
char). Remember that a byte is not always 8 bits.
> Must every conforming implementation be able to put a char at any byte
> address? If so, what part of the standard leads to this requirement?
Yes. It's fairly obvious from the memory model and the fact that bytes
and chars are the same size; I think [basic.types] has the necessary
language.
--
Alan Stokes (alan@rcp.co.uk)
RCP Consultants Ltd
Didcot, UK
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: WILLIAM SEYMOUR <WSEYMOUR@email.usps.gov>
Date: 1997/12/02 Raw View
Scott Meyers wrote:
>
> Is this really true? I'd heard that on Crays, each char was 32 bits
My understanding from things I've heard at J11/WG14 meetings is that
the Cray packs 4 chars in a word, so sizeof(int) is still 4. What
probably surprises a lot of folks is that a char* isn't a memory
address, but an address plus at least 2 more bits telling which
of the 4 chars at that address is being pointed to. (I seem to
remember hearing Tom MacDonald of Cray/SGI saying that he implements
a char* as a 2-word struct.)
--Bill Seymour (wseymour@email.usps.gov)
Programmer/Analyst, U.S. Postal Service
Vocabulary Representative, J11
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1997/12/03 Raw View
In article <65vpal$c4i$1@user2.teleport.com>, smeyers@teleport.com
says...
> In article <m3sote3vjh.fsf@gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
> | A char cannot have alignment requirements. Indirectly: it can be shown
> | that an implementation in which the alignment requirements of T are
> | greater than sizeof(T) cannot be conforming. And of course, since
> | sizeof( char ) is required to be 1, you must be able to put a char at
> | any byte address.
>
> Is this really true? I'd heard that on Crays, each char was 32 bits in
> length, though of course it was still the case that sizeof(char) was 1.
> Must every conforming implementation be able to put a char at any byte
> address? If so, what part of the standard leads to this requirement?
The last time I checked, on a Cray a char occupied only 8 bits.
However, even if it did occupy 32 bits, it would still be perfectly
fine. According to the C and C++ standards, a "byte" is defined as
the amount of storage occupied by a char. Therefore, if a char
occupied 32 bits, then on a Cray, a byte would BE 32 bits rather than
the 8 bits we generally expect. As such, if it required alignment to
a 32 bit boundary, that would be perfectly fine because that would BE
a byte boundary.
--
Later,
Jerry.
The Universe is a figment of its own imagination.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/12/03 Raw View
On 02 Dec 97 09:11:39 GMT, smeyers@teleport.com (Scott Meyers) wrote:
>In article <m3sote3vjh.fsf@gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
>| A char cannot have alignment requirements. Indirectly: it can be shown
>| that an implementation in which the alignment requirements of T are
>| greater than sizeof(T) cannot be conforming. And of course, since
>| sizeof( char ) is required to be 1, you must be able to put a char at
>| any byte address.
>
>Is this really true? I'd heard that on Crays, each char was 32 bits in
>length, though of course it was still the case that sizeof(char) was 1.
>Must every conforming implementation be able to put a char at any byte
>address? If so, what part of the standard leads to this requirement?
A byte is defined in the standard as the fundamental storage unit, and
which is at least large enough to contain any member of the basic
execution character set. If a char is 32 (or 36) bits, then so is a
byte, and there is no conflict. (The external representation of
characters is not an issue; only their representation inside a running
program.)
OTOH, if that implementation wants to pack character arrays using, for
example, 8 (or 9) bits per character, it would have a problem. You
must be able to take the address of any character in the array,
meaning the address of A[2] would fall between A and A+1. It might be
possible to keep such an implementation conforming, but I think it
would be tricky.
On the gripping hand, non-conforming implementations are not unheard
of. :-)
---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/11/04 Raw View
On 04 Nov 97 05:02:54 GMT, kanze@gabi-soft.fr (J. Kanze) wrote:
>
>|> In your example the alignment requirements of char must be specified,
>|> and if, as is likely, it is one then the padding needed for i *must*
>|> go after c2- the implementation has no choice.
>
>A char cannot have alignment requirements. Indirectly: it can be shown
>that an implementation in which the alignment requirements of T are
>greater than sizeof(T) cannot be conforming. And of course, since
>sizeof( char ) is required to be 1, you must be able to put a char at
>any byte address.
True, char must have an alignment of 1.
>
>|> 9.2 [class.mem]/12 is faulty in that it doesn't make this clear- it
>|> needs to add a sentence stating that "only the minimum necessary
>|> padding for the (implementation-specified) alignment requirements can
>|> be added."
>
>No. This is NOT what is wanted. On an Intel based machine, for
>example, the "minimum necessary padding" is always 0 -- an Intel
>processor can access any type at any address. Nevertheless, such
>accesses have a significant cost in run-time, and most compilers will
>probably consider that a larger alignment requirement is "appropriate".
Sorry, I wasn't clear here. I certainly didn't mean to imply that an
implementation should not be free to choose its alignment requirements
and should be limited to the hardware-required minimums- what I meant
was that, having specified its alignment requirements, padding can
only be added to achieve that, and that additional padding over and
above those requirements is disallowed.
>
>In practice, of course, the intent isn't that implementors add padding
>right and left just for the fun of it. It is to leave the implementors
>the freedom to decide for their implementation what they consider
>"appropriate". IMHO, this is the correct solution -- I dare say that a
>compiler that inserts totally useless padding according to some obtuse
>algorithm is not going to be a best seller.
But still, the standard's allowing an implementation the freedom to
add such gratuitous padding comes at the cost of less well defined
struct layout.
>
>|> In fact, this paragraph wants a good going over. Any chance that this
>|> issue will be discussed at the next standards meeting?
>
>Almost certainly not in the C++ standardization effort. For one thing,
>it is too late to introduce new questions now (and I don't believe that
>anyone raised the question earlier), and for another, this is also a C
>question: IMHO, the correct attitude of the C++ committee should be to
>leave it up to the C committee, and just follow whatever they do.
Actually, the main reason I raised this issue is that I thought that
it *had* been discussed and resolved by the committee in favour of
disallowing gratuitous padding, and that the CD2 simply had a typo in
[class.mem]/12.
Certainly, this was clearly the intent as stated in the C++ Report
article I previously cited ("Standard Update: The memory model-type
representations" Josee Lajoie, C++ Report, May 96.) which acknowledges
Tom Plum and Bill Plauger for the explanation of the memory model.
I quote from the article- " POD-classes: ... The alignment
restrictions may cause two adjacent members not to be allocated
immediately after each other. However the standard requires that these
members only be separated by the padding bits necessary to align the
second member according to the alignment restrictions of the
implementation." (followed by an example clearly demonstrating this).
It's a minor point in the grand scheme of things, but if it is a typo
then it would be a shame for it to make it into the final standard.
(BTW, 3.9.1/1 also clearly has a typo in it, see the thread "Major
hole on CD2 pointer conversions for details)
,Brian Parker.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/04 Raw View
bparker@mailbox.uq.edu.au (Brian Parker) writes:
|> But even within a single object file, the standard defines layout
|> compatible structs as depending only on member order, and indeed
|> allows a a common initial sequence of two structs in a union to be
|> accessed regardless of union member. ([class.mem/16]. I don't see how
|> that can be reconciled with arbitrary distribution of alignment
|> padding.
The implementation defines a canonical form of the typenames, and pads
according to a hash function over the canonical forms of the preceding
type names:-). I can't imagine such an implementation being
particularly popular in a competitive market (but then, I can't imagine
anyone choosing MS-Windows in a competitive market:-), but I'm fairly
sure that it would be conforming, as long as they documented the fact.
(Question: how detailed does the documentation have to be? I rather
suspect that just saying we use a hash code over a canonical form would
be sufficient, but it won't help much in figuring out the actual
padding.)
|> >I am against any constraits on the layout; I'd like to
|> >see the restriction that addresses of members are ordered
|> >removed).
|> >
|> >struct T { int a, b; } x;
|> >assert (&x.a < &x.b); // shouldn't be guarantied
|>
|> Perhaps, but the fact remains that it is the intent of the current
|> standard to completely determine the alignment layout- certainly that
|> was made quite clear in the C++ Report article I cited- and so
|> [class.mem]/12 needs to be fixed. I don't believe that it was ever
|> intended to allow leeway in distributing alignment padding, and if
|> that truly is the intent then *that* should be clarified in
|> [class.mem]/12.
It was certainly the intent of the C standard. An implementation for
Intel could choose space (no padding) or time (padding for alignment)
optimization, according to what it felt was appropriate. (At least some
implementations made this a compile time option. THAT must have led to
some interesting link errors:-).)
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/05 Raw View
J. Kanze wrote:
> An implementation for
> Intel could choose space (no padding) or time (padding for alignment)
> optimization, according to what it felt was appropriate. (At least some
> implementations made this a compile time option. THAT must have led to
> some interesting link errors:-).)
Not necessarily - if they mangle those types different (say, use an
P for packed structs and an S for unpacked structs), the linker could
provide meaningful error messages.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: herbs@cntc.com (Herb Sutter)
Date: 1997/11/01 Raw View
On 31 Oct 97 07:51:11 GMT, "Paul D. DeRocco" <pderocco@ix.netcom.com> wrote:
>Bill Wade wrote:
>> Her article certainly says the layout is correct even for non-POD (p. 82)
>> "... the later member [must] be allocated at a higher address within the
>> class object and these members ONLY be separated by [alignment padding]"
>> (emphasis mine). I'm not sure I can find the wording in CD2 which supports
>> her statement, but it goes a long way towards meeting my request.
It's in 9.2/12 [class.mem].
>I'm pretty sure I've read that the draft standard only makes
>that guarantee if there is no intervening "public:",
>"protected:" or "private:".
That's correct. To quote the True Scoop:
12Nonstatic data members of a (non-union) class declared without an
intervening access-specifier are allocated so that later members have
higher addresses within a class object. The order of allocation of
nonstatic data members separated by an access-specifier is unspecified
(_class.access.spec_). Implementation alignment requirements might
cause two adjacent members not to be allocated immediately after each
other; so might requirements for space for managing virtual functions
(_class.virtual_) and virtual base classes (_class.mi_).
See also 11.1/2.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/11/01 Raw View
Brian Parker wrote:
> I disagree with this-- being able to predict the layout of a POD
> knowing the implementation-defined alignment requirements is an
> essential part of the C/C++ memory model. If an implementation could
> non-deterministically rearrange padding within objects then no form of
> layout compatibility could be guaranteed.
Well, I don't know if the intent is that the layout is completly
implementation defined; the following are important to know the
layout:
- endian-ness
- signed number representation
- number of bits in the representation, which are
significants in unsigned values
- size of types
- alignement
- the way the padding is done
- physical address of members (could only be different from
the declaration order on very perverse implementations)
- how pointers are represented (do they contain a description
of the array they point to ?)
- do unions have a tag for checking ?
Not all of these are implementation defined.
So no form of layout compatibillity can be garantied by
the std. This is the role of ABI. Often #pragma let you
choose which representation you want (example with CW:
#pragma option align=powerpc).
I am against any constraits on the layout; I'd like to
see the restriction that addresses of members are ordered
removed).
struct T { int a, b; } x;
assert (&x.a < &x.b); // shouldn't be guarantied
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/11/02 Raw View
On 01 Nov 97 15:15:29 GMT, Valentin Bonnard <bonnardv@pratique.fr>
wrote:
>...
>Well, I don't know if the intent is that the layout is completly
>implementation defined; the following are important to know the
>layout:
>
>- endian-ness
>- signed number representation
>- number of bits in the representation, which are
> significants in unsigned values
>- size of types
>- alignement
>- the way the padding is done
>- physical address of members (could only be different from
> the declaration order on very perverse implementations)
>- how pointers are represented (do they contain a description
> of the array they point to ?)
>- do unions have a tag for checking ?
>
>Not all of these are implementation defined.
>
>So no form of layout compatibillity can be garantied by
>the std. This is the role of ABI. Often #pragma let you
>choose which representation you want (example with CW:
>#pragma option align=powerpc).
When linking with an object file compiled by another compiler/language
then certainly the alignment requirements are necessary but not
sufficient for sharing structs, and the other undefined aspects such
as endian-ness etc. would need to be known, but in any case they will
typically be the same on a given system.
But even within a single object file, the standard defines layout
compatible structs as depending only on member order, and indeed
allows a a common initial sequence of two structs in a union to be
accessed regardless of union member. ([class.mem/16]. I don't see how
that can be reconciled with arbitrary distribution of alignment
padding.
>
>I am against any constraits on the layout; I'd like to
>see the restriction that addresses of members are ordered
>removed).
>
>struct T { int a, b; } x;
>assert (&x.a < &x.b); // shouldn't be guarantied
Perhaps, but the fact remains that it is the intent of the current
standard to completely determine the alignment layout- certainly that
was made quite clear in the C++ Report article I cited- and so
[class.mem]/12 needs to be fixed. I don't believe that it was ever
intended to allow leeway in distributing alignment padding, and if
that truly is the intent then *that* should be clarified in
[class.mem]/12.
,Brian Parker.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/04 Raw View
bparker@mailbox.uq.edu.au (Brian Parker) writes:
|> On 31 Oct 97 14:18:15 GMT, kanze@gabi-soft.fr (J. Kanze) wrote:
|> >...
|> >
|> >The allowed padding is to ensure "appropriate" alignment. The
|> >implementation is free to decide whatever it wants with regards to what
|> >is appropriate -- for example, an implementation might decide that all
|> >structure elements are aligned on 4 byte boundaries.
|> >
|> >Also, the implementation is free to put the padding whereever it likes
|> >(except at the beginning). Thus, assuming 4 byte alignment requirement
|> >for int's, consider the following:
|> >
|> > struct X { char c1 ; char c2 ; int i ; } ;
|> >
|> >It is obvious that the implementation must put two bytes of padding
|> >somewhere before i. Whether these bytes are before c2, after c2, or one
|> >before, one after, is up to the implementation.
|>
|> I disagree with this-- being able to predict the layout of a POD
|> knowing the implementation-defined alignment requirements is an
|> essential part of the C/C++ memory model. If an implementation could
|> non-deterministically rearrange padding within objects then no form of
|> layout compatibility could be guaranteed.
I didn't say that it was non-deterministic -- I said that it was up to
the implementation. Whether there is padding, and if there is, where it
is placed, is implementation defined. If the implementation chooses
some strange algorithm for spreading the padding out, and documents this
choice, it is conforming.
|> In your example the alignment requirements of char must be specified,
|> and if, as is likely, it is one then the padding needed for i *must*
|> go after c2- the implementation has no choice.
A char cannot have alignment requirements. Indirectly: it can be shown
that an implementation in which the alignment requirements of T are
greater than sizeof(T) cannot be conforming. And of course, since
sizeof( char ) is required to be 1, you must be able to put a char at
any byte address.
|> 9.2 [class.mem]/12 is faulty in that it doesn't make this clear- it
|> needs to add a sentence stating that "only the minimum necessary
|> padding for the (implementation-specified) alignment requirements can
|> be added."
No. This is NOT what is wanted. On an Intel based machine, for
example, the "minimum necessary padding" is always 0 -- an Intel
processor can access any type at any address. Nevertheless, such
accesses have a significant cost in run-time, and most compilers will
probably consider that a larger alignment requirement is "appropriate".
In practice, of course, the intent isn't that implementors add padding
right and left just for the fun of it. It is to leave the implementors
the freedom to decide for their implementation what they consider
"appropriate". IMHO, this is the correct solution -- I dare say that a
compiler that inserts totally useless padding according to some obtuse
algorithm is not going to be a best seller.
|> In fact, this paragraph wants a good going over. Any chance that this
|> issue will be discussed at the next standards meeting?
Almost certainly not in the C++ standardization effort. For one thing,
it is too late to introduce new questions now (and I don't believe that
anyone raised the question earlier), and for another, this is also a C
question: IMHO, the correct attitude of the C++ committee should be to
leave it up to the C committee, and just follow whatever they do.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/31 Raw View
Bill Wade wrote:
>
> Her article certainly says the layout is correct even for non-POD (p. 82)
> "... the later member [must] be allocated at a higher address within the
> class object and these members ONLY be separated by [alignment padding]"
> (emphasis mine). I'm not sure I can find the wording in CD2 which supports
> her statement, but it goes a long way towards meeting my request.
I'm pretty sure I've read that the draft standard only makes
that guarantee if there is no intervening "public:",
"protected:" or "private:". That is, it leaves wiggle room for
implementations that wish to rearrange members according to
their access restrictions. Personally, I can't imagine why that
would be advantageous.
--
Ciao,
Paul
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/31 Raw View
bparker@mailbox.uq.edu.au (Brian Parker) writes:
|> On 30 Oct 97 08:17:17 GMT, "Bill Wade" <bill.wade@stoner.com> wrote:
|>
|> >I'd like the standard to promise that adjacent, non-static, data members
|> >of a class support array semantics (assuming those members all have the
|> >same type).
|> >
|> >class Foo
|> >{
|> > ...
|> > T a;
|> > T b;
|> > T c;
|> > ...
|> >} x;
|> >
|> >I'd like a promise that
|> > &x.c == &x.a + 2; // Assuming built-in '&'
|> >Obviously if 'b' and 'a' have different types then array semantics don't
|> >make sense.
[...]
|> I've just been reading up on the C++ memory model for other purposes
|> and I believe that the draft standard in fact already guarantees your
|> suggestion- certainly for POD types. The draft states that a POD is
|> stored in contiguous memory and that succesive elements are stored in
|> address order. Moreover, the only padding allowed between members is
|> for alignment purposes but successive elements of the same type need
|> no padding by definition (all types must be able to be stored
|> contiguously in an array and so any needed padding must have been
|> already added as part of the type). Also, there is guaranteed to be no
|> padding before the first element of a POD.
The allowed padding is to ensure "appropriate" alignment. The
implementation is free to decide whatever it wants with regards to what
is appropriate -- for example, an implementation might decide that all
structure elements are aligned on 4 byte boundaries.
Also, the implementation is free to put the padding whereever it likes
(except at the beginning). Thus, assuming 4 byte alignment requirement
for int's, consider the following:
struct X { char c1 ; char c2 ; int i ; } ;
It is obvious that the implementation must put two bytes of padding
somewhere before i. Whether these bytes are before c2, after c2, or one
before, one after, is up to the implementation.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/10/31 Raw View
On 31 Oct 97 14:18:15 GMT, kanze@gabi-soft.fr (J. Kanze) wrote:
>...
>
>The allowed padding is to ensure "appropriate" alignment. The
>implementation is free to decide whatever it wants with regards to what
>is appropriate -- for example, an implementation might decide that all
>structure elements are aligned on 4 byte boundaries.
>
>Also, the implementation is free to put the padding whereever it likes
>(except at the beginning). Thus, assuming 4 byte alignment requirement
>for int's, consider the following:
>
> struct X { char c1 ; char c2 ; int i ; } ;
>
>It is obvious that the implementation must put two bytes of padding
>somewhere before i. Whether these bytes are before c2, after c2, or one
>before, one after, is up to the implementation.
I disagree with this-- being able to predict the layout of a POD
knowing the implementation-defined alignment requirements is an
essential part of the C/C++ memory model. If an implementation could
non-deterministically rearrange padding within objects then no form of
layout compatibility could be guaranteed.
In your example the alignment requirements of char must be specified,
and if, as is likely, it is one then the padding needed for i *must*
go after c2- the implementation has no choice.
9.2 [class.mem]/12 is faulty in that it doesn't make this clear- it
needs to add a sentence stating that "only the minimum necessary
padding for the (implementation-specified) alignment requirements can
be added."
In fact, this paragraph wants a good going over. Any chance that this
issue will be discussed at the next standards meeting?
,Brian Parker.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1997/10/31 Raw View
Paul D. DeRocco <pderocco@ix.netcom.com> wrote in article
<34593E3F.72B62BBB@ix.netcom.com>...
> I'm pretty sure I've read that the draft standard only makes
> that guarantee if there is no intervening "public:",
> "protected:" or "private:".
Correct.
> That is, it leaves wiggle room for
> implementations that wish to rearrange members according to
> their access restrictions. Personally, I can't imagine why that
> would be advantageous.
It does allow some space optimizations. A contrived example
struct Foo
{
public: char a;
public: int c;
public: char b;
};
On a machine where alignment of int is 2, a compiler might put 'b' before
'c' and avoid padding. I don't know of any implementations which do this,
but I wouldn't be terribly surprised if they exist.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/10/30 Raw View
On 30 Oct 97 08:17:17 GMT, "Bill Wade" <bill.wade@stoner.com> wrote:
>I'd like the standard to promise that adjacent, non-static, data members of
>a class support array semantics (assuming those members all have the same
>type).
>
>class Foo
>{
> ...
> T a;
> T b;
> T c;
> ...
>} x;
>
>I'd like a promise that
> &x.c == &x.a + 2; // Assuming built-in '&'
>Obviously if 'b' and 'a' have different types then array semantics don't
>make sense.
>
>I don't believe this puts unreasonable constraints on implementations. I'd
>be surprised to see an implementation where this wasn't true (except a
>bounds-checking implementation might consider (&x.a+2) to be out of
>bounds).
>
>The guarantee may already apply for elements at the beginning of a POD
>struct, I'm not sure. It also may already apply if the elements are placed
>in a struct and unioned with an array of T, but that would only be
>applicable for simple classes. I can't find any clear wording that the
>guarantee applies in general.
>
>This provides a low-maintenance mechanism to support both enumeration and
>efficient named access of members. You can approximate this behavior with
>an array or vector class, and an enum for array indices, but only with
>added difficulty.
I've just been reading up on the C++ memory model for other purposes
and I believe that the draft standard in fact already guarantees your
suggestion- certainly for POD types. The draft states that a POD is
stored in contiguous memory and that succesive elements are stored in
address order. Moreover, the only padding allowed between members is
for alignment purposes but successive elements of the same type need
no padding by definition (all types must be able to be stored
contiguously in an array and so any needed padding must have been
already added as part of the type). Also, there is guaranteed to be no
padding before the first element of a POD.
The situation for non-PODs is similar provided the elements are not
separated by access specifiers. The one issue I am not certain about
is whether, for classes with virtual functions or bases, an
implementation is allowed to add addition data for virtual tables and
base ptrs *amongst* the elements or only between groups of elements
separated by access speciifiers. In fact [class.mem]/12 suggests that
such data can be strewn anywhere- perhaps it should be strengthened to
say that such data can only be added between groups?
A good reference is the article "Standard Update: The memory
model-type representations" Josee Lajoie, C++ Report, May 96.
,Brian Parker.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1997/10/30 Raw View
Brian Parker <bparker@mailbox.uq.edu.au> wrote in article
<34585b3a.14501388@news.uq.edu.au>...
>
> A good reference is the article "Standard Update: The memory
> model-type representations" Josee Lajoie, C++ Report, May 96.
>
Her article certainly says the layout is correct even for non-POD (p. 82)
"... the later member [must] be allocated at a higher address within the
class object and these members ONLY be separated by [alignment padding]"
(emphasis mine). I'm not sure I can find the wording in CD2 which supports
her statement, but it goes a long way towards meeting my request.
However even if the layout is correct, the standard doesn't support
pointer+integer math for non-array pointers. Given
struct{ T a,b,c; } x;
T* pa = &x.a;
T* pc = pa + 2;
The addition on the last line is "undefined behavior" according to the
standard, even if x.c has to be at the right place. In particular a
bounds-checking implementation might mark 'pa' as a non array or an array
of size 1, and 'fault' on the addition.
On a related question is a pointer one past a non-array object valid (if
not dereferenced)?
int x = 2;
int y;
std::copy(&x, &x+1, &y); // Is this conforming?
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1997/10/30 Raw View
I'd like the standard to promise that adjacent, non-static, data members of
a class support array semantics (assuming those members all have the same
type).
class Foo
{
...
T a;
T b;
T c;
...
} x;
I'd like a promise that
&x.c == &x.a + 2; // Assuming built-in '&'
Obviously if 'b' and 'a' have different types then array semantics don't
make sense.
I don't believe this puts unreasonable constraints on implementations. I'd
be surprised to see an implementation where this wasn't true (except a
bounds-checking implementation might consider (&x.a+2) to be out of
bounds).
The guarantee may already apply for elements at the beginning of a POD
struct, I'm not sure. It also may already apply if the elements are placed
in a struct and unioned with an array of T, but that would only be
applicable for simple classes. I can't find any clear wording that the
guarantee applies in general.
This provides a low-maintenance mechanism to support both enumeration and
efficient named access of members. You can approximate this behavior with
an array or vector class, and an enum for array indices, but only with
added difficulty.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]