Topic: alignment


Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/11/07
Raw View
On 05 Nov 97 13:42:00 GMT, "Paul D. DeRocco" <pderocco@ix.netcom.com>
wrote:

>Steve Clamage wrote:
>>
>> The desire for a more general offsetof in this thread seems motivated
>> by a desire to find alignment requirements. That problem could be
>> addressed directly by adding "alignof" to the language, as indeed some
>> compilers do as an extension. I don't know of any reason why it
>> couldn't be added to the C++ standard. It is trivial to implement in a
>> typicaly compiler. But I don't remember ever seeing a formal proposal
>> to add it.
>
>And an implementation would be free to define it as a macro that
>uses the offsetof mechanism, as long as offsetof produced
>meaningful results for non-POD types within that implementation.
>Only those implementations that actually play tricks that make
>the offsetof technique fail would have to build in a special
>alignof function.

Since we are talking about the implementation, it is easier and more
reliable to add the feature to the compiler.

The compiler knows the alignment requirements of every type. An
intrinsic function that works exactly like sizeof can be added to a
typical compiler with virtually no effort, and is certain not to have
any effect on any valid program.

A macro would have to do something along the lines of adding a useless
type definition, then invoke offsetof. That strikes me as a much
inferior solution (for the implementor), adding compile-time
complexity each time it is used in a program.

Users (as opposed to implementors) can define a template as discussed
in other articles.

Adding alignof to the language would provide a standard way to find
alignment.

---
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: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/05
Raw View
Steve Clamage wrote:
>
> The desire for a more general offsetof in this thread seems motivated
> by a desire to find alignment requirements. That problem could be
> addressed directly by adding "alignof" to the language, as indeed some
> compilers do as an extension. I don't know of any reason why it
> couldn't be added to the C++ standard. It is trivial to implement in a
> typicaly compiler. But I don't remember ever seeing a formal proposal
> to add it.

And an implementation would be free to define it as a macro that
uses the offsetof mechanism, as long as offsetof produced
meaningful results for non-POD types within that implementation.
Only those implementations that actually play tricks that make
the offsetof technique fail would have to build in a special
alignof function.

--

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: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/11/07
Raw View
On 04 Nov 97 05:12:19 GMT, stephen.clamage_nospam@eng.sun.com (Steve
Clamage) wrote:
>..
>The desire for a more general offsetof in this thread seems motivated
>by a desire to find alignment requirements. That problem could be
>addressed directly by adding "alignof" to the language, as indeed some
>compilers do as an extension.
>...

Yes, and perhaps a standard traits class could be added that returns a
typedef for an (implementation-specific) builtin or POD type with a
given alignment so that e.g.

union {
 align_traits<alignof(T)>::align dummy;
 char my_buffer[N * sizeof(T)];
}

would be guaranteed to give an aligned buffer (On his web site,
Valentin Bonnard has implemented a portable template class which
should give similar results on most (all?) machines, but this is not
guaranteed).

It is a minor flaw in the current (draft) standard that there is no
portable way to get the alignment information which is essential for
using placment new from a static buffer.

(Loosening the restrictions on offsetof( ) so that it is guaranteed to
work for types which would be PODs except for non-POD members would at
least be a partial solution).

,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: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/11/04
Raw View
On 31 Oct 97 16:47:53 GMT, bparker@mailbox.uq.edu.au (Brian Parker)
wrote:

>In fact, I think that the draft standard definition of offsetof( )  is
>overconstrained- I think it could state that it must work for any
>class without virtual functions or virtual bases; I think it has been
>unnecessarily limited to POD types purely for ease of specification.

There isn't a lot of room between POD classes and classes without
virtual functions or virtual bases. Specification and use of offsetof
is a bit tricky when base classes are involved. There isn't much real
need for offsetof in C++ classes, since you can get the effect with
pointer-to-member. Consequently, we decided not to try to draw the
finest possible distinctions, and left offsetof for C compatibility on
C-compatible classes.

The desire for a more general offsetof in this thread seems motivated
by a desire to find alignment requirements. That problem could be
addressed directly by adding "alignof" to the language, as indeed some
compilers do as an extension. I don't know of any reason why it
couldn't be added to the C++ standard. It is trivial to implement in a
typicaly compiler. But I don't remember ever seeing a formal proposal
to add it.

---
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: "Bill Wade" <bill.wade@stoner.com>
Date: 1997/11/05
Raw View
Brian Parker <bparker@mailbox.uq.edu.au> wrote in article
<345a0c9f.2723445@news.uq.edu.au>...
> That's gotta be illegal, such an implementation would be overlapping
> adjacent objects- the size of an X is sizeof(X) (if that's not too
> tautological) regardless of whether it actually uses all of those
> bytes for its value. 9.2 [class.mem]/12 obviously intends for members
> to be adjacent to each other except for the minimum alignment padding
> needed, though, on rereading it, it certainly doesn't clearly prohibit
> overlapping with previous members. Perhaps some clarifying words are
> needed here?

POD members may not overlap each other or any "important" bits of a non-pod
object.

class Foo { POD x; T y; } a, b;

memcpy(a.x, b.x, sizeof(POD));

The memcpy must have the same semantics as assignment, and must have no
observable effect on a.y.  I'm less sure about about dataless non-POD
objects:

class Empty { public: ~Empty(); };

class T1 : public Empty { int i; } t1;

Note that sizeof(Empty) is at least 1.

I pretty sure it is legal for
  (char*)(Empty*) &t1 == (char*)&t1.i;
meaning the empty part of t1 has the same address as t1.i.  If so
sizeof(T1) may equal sizeof(int).  At least I remember hearing that empty
base classes don't have to add to the size of derived classes.

I'm much less certain that for
  class T2 { int i; Empty j; } t2;
it is legal for
  (char*) &t2.j to be in the range [ (char*)&t2.i, (char*)(&t2.i+1) )
because of arguments about distinct objects having distinct addresses.
Note that if Empty were POD it certainly couldn't overlap because of the
memcpy argument above.
---
[ 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 16:47:53 GMT, bparker@mailbox.uq.edu.au (Brian Parker)
wrote:
>>|>  offsetof (Off, t) is the alignment of T
>>
>>This is only legal if T is a POD -- if T is not a POD, then struct Off
>>is not a PODS, and using offsetof on it is undefined behavior.
>
>Yes, I agree that this is a potential problem but I think that in
>practice, the fact that T is a non-POD would not change the layout of

As Steve Clamage said recently in this newsgroup: since this is
comp.STD.c++, the argument "works on many compilers" is not
interesting. :-)
---
[ 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:09:19 GMT, herbs@cntc.com (Herb Sutter) wrote:

>>
>>Yes, I agree that this is a potential problem but I think that in
>>practice, the fact that T is a non-POD would not change the layout of
>
>As Steve Clamage said recently in this newsgroup: since this is
>comp.STD.c++, the argument "works on many compilers" is not
>interesting. :-)

True, and given that this technique is the most straightforward
(only?) method to get the (important) alignment information (my
earlier template using sizeof would suffer from the same problem),
then I think that the restrictions on offsetof( ) should be weakened
to allow it i.e. state that offsetof( ) works for any class that would
be classified as a POD except for its members being non-POD.
I can't see any reason why offsetof( ) couldn't be written to work in
this case as well- the obvious implementation should work unchanged.

,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: Paul Black <paul.black@vf.vodafone.co.uk>
Date: 1997/11/03
Raw View
bparker@mailbox.uq.edu.au (Brian Parker) wrote:
> The alignment requirements can't be too wild- they are an
> implementation-defined value, so an implementation need to document
> them and I don't believe that they could conceivably vary within an
> address-space or at run time (in fact, I think you could actually
> prove that some how from the standard) e.g. how could an struct member
> be handled without varying the layout at run-time?

At the time I couldn't think of a scheme where the alignment for a
type may differ under different circumstances of use. What has since
occured to me is that MSC (5.1, and 6.0), if I remember correctly,
used two-byte alignments for chars on the stack but a one-byte
alignment in all other cases. How would such alignment requirements
be dealt with through a traits class?

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/11/04
Raw View
herbs@cntc.com (Herb Sutter) writes:

|>  On 31 Oct 97 16:47:53 GMT, bparker@mailbox.uq.edu.au (Brian Parker)
|>  wrote:
|>  >>|>  offsetof (Off, t) is the alignment of T
|>  >>
|>  >>This is only legal if T is a POD -- if T is not a POD, then struct Off
|>  >>is not a PODS, and using offsetof on it is undefined behavior.
|>  >
|>  >Yes, I agree that this is a potential problem but I think that in
|>  >practice, the fact that T is a non-POD would not change the layout of
|>
|>  As Steve Clamage said recently in this newsgroup: since this is
|>  comp.STD.c++, the argument "works on many compilers" is not
|>  interesting. :-)

So he should move the discussion to comp.lang.c++.moderated?  In fact,
in the case where many==all, and there is no reasonable implementation
where it wouldn't work, I'm not sure.  The problem comes up when
reserving memory on which a placement new will be used -- just writing
"unsigned char raw[ sizeof( T ) ]" doesn't work, because there are no
alignment constraints on the buffer, whereas there are on T.  (In
practice, it really doesn't work in some cases with Sun CC, and no doubt
many other compilers.  So it is not an academic question.)  On the other
hand, declaring the buffer to be a union of this and of MaxAlign, which
is itself a union of a large number of types, does work, and will
continue to work on all "reasonable" compilers, even if the standard
doesn't formally guarantee it.

I find such pseudo-guarantees useful.

--
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: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/04
Raw View
Paul Black <paul.black@vf.vodafone.co.uk> writes:

>At the time I couldn't think of a scheme where the alignment for a
>type may differ under different circumstances of use. What has since
>occured to me is that MSC (5.1, and 6.0), if I remember correctly,
>used two-byte alignments for chars on the stack but a one-byte
>alignment in all other cases. How would such alignment requirements
>be dealt with through a traits class?

In such a case, the most obvious way of looking at it is that
the alignment requirement for chars is one-byte alignment,
it is just that the compiler chooses to align chars on the
stack more than is required.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ 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/04
Raw View
Paul Black <paul.black@vf.vodafone.co.uk> writes:

> At the time I couldn't think of a scheme where the alignment for a
> type may differ under different circumstances of use. What has since
> occured to me is that MSC (5.1, and 6.0), if I remember correctly,
> used two-byte alignments for chars on the stack but a one-byte
> alignment in all other cases. How would such alignment requirements
> be dealt with through a traits class?

If the char is just an auto variable, then it's ok. OTOH, if
it's part of a struct:

struct T {
    char c1, c2;
};

then the layout of the struct should be the same on the stack
and in other areas. In particular, offsetof, and pointers to
members should work the same.

--

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/04
Raw View
On 03 Nov 97 11:12:39 GMT, Paul Black <paul.black@vf.vodafone.co.uk>
wrote:

>bparker@mailbox.uq.edu.au (Brian Parker) wrote:
>> The alignment requirements can't be too wild- they are an
>> implementation-defined value, so an implementation need to document
>> them and I don't believe that they could conceivably vary within an
>> address-space or at run time (in fact, I think you could actually
>> prove that some how from the standard) e.g. how could an struct member
>> be handled without varying the layout at run-time?
>
>At the time I couldn't think of a scheme where the alignment for a
>type may differ under different circumstances of use. What has since
>occured to me is that MSC (5.1, and 6.0), if I remember correctly,
>used two-byte alignments for chars on the stack but a one-byte
>alignment in all other cases. How would such alignment requirements
>be dealt with through a traits class?

Hmmm... perhaps I spake too soon.

But the true alignment restriction of a char can't be > 1 as arrays of
chars must be stored with no alignment padding. So, even though MSC
may choose to align chars with a two-byte alignment on the stack, from
a programmer's perspective, when allocating chars from a buffer on the
stack he would only be limited by an alignment of 1.

Actually, a more compelling reason why a fixed traits class would not
be too useful is that, generally, the alignment restriction of a
struct depends on its members, hence a traits class would need to give
the less useful worst-case alignment for all structs.

...I've gone right off the traits idea.

,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
<34585619.13188855@news.uq.edu.au>...
>
> Can anyone find any non-conforming aspects of this code?

Neat.  I minor gripe, it requires T to have a default constructor.

I believe your examples work even without the t1 member.

I think an implementation can have special alignment restrictions for any
structs (all struct pointers smell the same, but they may be different from
char pointers).  So
  struct CC { char a,b; };
  assert(sizeof(CC) == 8); // This might work on some system
However your trick should work for any T which is a struct.  In any case it
provides a fairly low upper bound on alignment restrictions (sizeof(T) is
another upper bound).
---
[ 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 30 Oct 97 17:28:23 GMT, "Bill Wade" <bill.wade@stoner.com> wrote:

>Brian Parker <bparker@mailbox.uq.edu.au> wrote in article
><34585619.13188855@news.uq.edu.au>...
>>
>> Can anyone find any non-conforming aspects of this code?
>
>Neat.  I minor gripe, it requires T to have a default constructor.

Does it? I thought that because the default constructor of AlignTest
is never called and hence not generated, then no call to T's default
constructor will ever be made and so it should also work for a T
without a default constructor.

>
>I believe your examples work even without the t1 member.

True.

>
>I think an implementation can have special alignment restrictions for any
>structs (all struct pointers smell the same, but they may be different from
>char pointers).  So
>  struct CC { char a,b; };
>  assert(sizeof(CC) == 8); // This might work on some system
>However your trick should work for any T which is a struct.  In any case it
>provides a fairly low upper bound on alignment restrictions (sizeof(T) is
>another upper bound).

Again, the (better) offsetof solution should work in this case as
well.

,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/10/31
Raw View
bparker@mailbox.uq.edu.au (Brian Parker) writes:

|>  Actually, just after my previous posting  I realised that one can find
|>  the alignment of any type at compile-time by using the following code-
|>
|>  template<class T>
|>  struct AlignTest1{
|>   T t1;
|>   T t2;
|>  };
|>
|>  template<class T>
|>  struct AlignTest2{
|>   T t1;
|>   char c;
|>   T t2;
|>  };
|>
|>  template<class T>
|>  struct Alignment {
|>   enum {val = sizeof(AlignTest2<T>) - sizeof(AlignTest1<T>)};
|>  };
|>
|>  class FF {
|>   int i;
|>   double d;
|>  };
|>
|>  int main()
|>  {
|>   FF f;
|>   std::cout << Alignment<FF>::val << '\n';
|>  }
|>
|>  I believe that this is completely portable and will work on any
|>  conforming implementation; it works well under VC++ 5.0 with any
|>  compiler alignment option (disclaimer- I haven't done exhaustive
|>  testing yet).

Well, it does have the restriction of not working for references.  But
since references are defined as not necessarily occupying space, I'm not
sure that this is a handicap.

|>  The char in AlignTest2 will force the second T2 to a new alignment
|>  boundary and so increase the size of AlignTest2. This is guaranteed, I
|>  think, because for a POD type ONLY alignment padding is allowed to be
|>  added, and even if T were a non-POD type, the only other applicable
|>  padding is for virtual tables and virtual bases, neither of which are
|>  an issue for AlignTest1 and 2.
|>
|>  Can anyone find any non-conforming aspects of this code?

I'm not sure: it concerns one point that isn't clear to me (either in C
or C++).  Consider the following structure:

    struct X { int i ; char c ; } ;

Now take a typical implementation, with 4 byte int's, requiring 4 byte
alignment.  I am unable to tell, from the standard, whether an
implementation could legally insert the char in AlignTest2 immediatly
after this struct, without any padding.  Note that this would lead to
the somewhat surprising result of "offsetof( AlignTest2<X> , c ) <
sizeof( T )", and even "sizeof( AlignTest2<X> ) < 2*sizeof(X)+1".

Although I can find nothing that directly forbids this in the standard,
I think that the standard would guarantee, in the above, that "memset(
&someAlignType2<X>.t1 , 0 , sizeof( X ) )" would not modify the value of
"c".  Which indirectly renders my suggested implementation illegal.

--
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: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/31
Raw View
bparker@mailbox.uq.edu.au (Brian Parker) writes:

|>  On 30 Oct 97 10:12:54 GMT, I  bparker@mailbox.uq.edu.au (Brian Parker)
|>  wrote:
|>
|>  >Actually, just after my previous posting  I realised that one can find
|>  >the alignment of any type at compile-time by using the following code-
|>  >... <code snipped>
|>
|>  Forget my previous post- an even simpler way to get the alignment-
|>  suggested by Valentin Bonnard- is simply to use offsetof( ),
|>
|>  struct Off {
|>      char c;
|>      T t;
|>  };
|>
|>  offsetof (Off, t) is the alignment of T

This is only legal if T is a POD -- if T is not a POD, then struct Off
is not a PODS, and using offsetof on it is undefined behavior.

--
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:13:10 GMT, kanze@gabi-soft.fr (J. Kanze) wrote:

>|>
>|>  struct Off {
>|>      char c;
>|>      T t;
>|>  };
>|>
>|>  offsetof (Off, t) is the alignment of T
>
>This is only legal if T is a POD -- if T is not a POD, then struct Off
>is not a PODS, and using offsetof on it is undefined behavior.

Yes, I agree that this is a potential problem but I think that in
practice, the fact that T is a non-POD would not change the layout of
Off, and, indeed, 9.2 [class.mem]/12 states that padding can only be
added for managing virtual functions and virtual base classes, neither
of which apply to Off regardless of T.

In fact, I think that the draft standard definition of offsetof( )  is
overconstrained- I think it could state that it must work for any
class without virtual functions or virtual bases; I think it has been
unnecessarily limited to POD types purely for ease of specification.

,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: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/10/31
Raw View
On 31 Oct 97 14:14:50 GMT, kanze@gabi-soft.fr (J. Kanze) wrote:

>
>I'm not sure: it concerns one point that isn't clear to me (either in C
>or C++).  Consider the following structure:
>
>    struct X { int i ; char c ; } ;
>
>Now take a typical implementation, with 4 byte int's, requiring 4 byte
>alignment.  I am unable to tell, from the standard, whether an
>implementation could legally insert the char in AlignTest2 immediatly
>after this struct, without any padding.  Note that this would lead to
>the somewhat surprising result of "offsetof( AlignTest2<X> , c ) <
>sizeof( T )", and even "sizeof( AlignTest2<X> ) < 2*sizeof(X)+1".
>
>Although I can find nothing that directly forbids this in the standard,
>I think that the standard would guarantee, in the above, that "memset(
>&someAlignType2<X>.t1 , 0 , sizeof( X ) )" would not modify the value of
>"c".  Which indirectly renders my suggested implementation illegal.

That's gotta be illegal, such an implementation would be overlapping
adjacent objects- the size of an X is sizeof(X) (if that's not too
tautological) regardless of whether it actually uses all of those
bytes for its value. 9.2 [class.mem]/12 obviously intends for members
to be adjacent to each other except for the minimum alignment padding
needed, though, on rereading it, it certainly doesn't clearly prohibit
overlapping with previous members. Perhaps some clarifying words are
needed here?

,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: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/10/30
Raw View
On 30 Oct 97 08:05:27 GMT, Paul Black <paul.black@vf.vodafone.co.uk>
wrote:
>...
>An approximation to worst case alignment (WCA) for a system is
>"min(sizeof(long), sizeof(long double)". There are probably systems
>where this doesn't hold for structs/classes. For a built-in type,
>sizeof(T) is probably sufficient.
>
>
>> I suspect that there isn't. If not, I think that the worst-case
>> alignment requirements should be defined in one of the standard
>> headers (maybe in the next C revision?), or, better, some standard
>> traits class could give this information for any given built-in type.
>
>This is probably not that easy to specify. If you try, someone is
>bound to bring out a processor that has alignment rules that can't
>be easily interrogated, e.g. if you are accessing an int if one
>part of memory, the alignment is this, and another part of memory it
>is something else or ints can only be aligned on even parity
>addresses.
The alignment requirements can't be too wild- they are an
implementation-defined value, so an implementation need to document
them and I don't believe that they could conceivably vary within an
address-space or at run time (in fact, I think you could actually
prove that some how from the standard) e.g. how could an struct member
be handled without varying the layout at run-time?

>
>The best that might be achievable with a traits class to say
>whether an address is valid for a built-in or what the next
>valid address is.

Actually, just after my previous posting  I realised that one can find
the alignment of any type at compile-time by using the following code-

template<class T>
struct AlignTest1{
 T t1;
 T t2;
};

template<class T>
struct AlignTest2{
 T t1;
 char c;
 T t2;
};

template<class T>
struct Alignment {
 enum {val = sizeof(AlignTest2<T>) - sizeof(AlignTest1<T>)};
};

class FF {
 int i;
 double d;
};

int main()
{
 FF f;
 std::cout << Alignment<FF>::val << '\n';
}

I believe that this is completely portable and will work on any
conforming implementation; it works well under VC++ 5.0 with any
compiler alignment option (disclaimer- I haven't done exhaustive
testing yet).

The char in AlignTest2 will force the second T2 to a new alignment
boundary and so increase the size of AlignTest2. This is guaranteed, I
think, because for a POD type ONLY alignment padding is allowed to be
added, and even if T were a non-POD type, the only other applicable
padding is for virtual tables and virtual bases, neither of which are
an issue for AlignTest1 and 2.

Can anyone find any non-conforming aspects of this code?

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: Paul Black <paul.black@vf.vodafone.co.uk>
Date: 1997/10/30
Raw View
bparker@mailbox.uq.edu.au (Brian Parker) wrote:
> My question for the newsgroup is- is there any portable standard way
> to find out the worst case alignment requirements of a system (or
> better, the alignment requirements of any given type)?

An approximation to worst case alignment (WCA) for a system is
"min(sizeof(long), sizeof(long double)". There are probably systems
where this doesn't hold for structs/classes. For a built-in type,
sizeof(T) is probably sufficient.


> I suspect that there isn't. If not, I think that the worst-case
> alignment requirements should be defined in one of the standard
> headers (maybe in the next C revision?), or, better, some standard
> traits class could give this information for any given built-in type.

This is probably not that easy to specify. If you try, someone is
bound to bring out a processor that has alignment rules that can't
be easily interrogated, e.g. if you are accessing an int if one
part of memory, the alignment is this, and another part of memory it
is something else or ints can only be aligned on even parity
addresses.

The best that might be achievable with a traits class to say
whether an address is valid for a built-in or what the next
valid address is.

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: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/10/30
Raw View
On 30 Oct 97 10:12:54 GMT, I  bparker@mailbox.uq.edu.au (Brian Parker)
wrote:

>Actually, just after my previous posting  I realised that one can find
>the alignment of any type at compile-time by using the following code-
>... <code snipped>

Forget my previous post- an even simpler way to get the alignment-
suggested by Valentin Bonnard- is simply to use offsetof( ),

struct Off {
    char c;
    T t;
};

offsetof (Off, t) is the alignment of T

(BTW, there is a thread in comp.lang.c++.moderated "How to find
alignment restrictions? " discussing this issue, followups should
probably go there.)

,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: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/10/29
Raw View
On 26 Oct 97 08:30:24 GMT, seurer@rchland.ibm.com (Bill Seurer) wrote:

>Some people seem to be arguing that alignment is a compiler
>implementation issue only.  Not so!  Just this week I helped someone work
>through problems in some code caused by not understanding the
>implications of alignment and the use of placement new.

I too have needed to be aware of alignment issues when using placement
new from a static buffer in several recent classes.

My question for the newsgroup is- is there any portable standard way
to find out the worst case alignment requirements of a system (or
better, the alignment requirements of any given type)?

I suspect that there isn't. If not, I think that the worst-case
alignment requirements should be defined in one of the standard
headers (maybe in the next C revision?), or, better, some standard
traits class could give this information for any given built-in type.

,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: seurer@rchland.ibm.com (Bill Seurer)
Date: 1997/10/26
Raw View
Some people seem to be arguing that alignment is a compiler
implementation issue only.  Not so!  Just this week I helped someone work
through problems in some code caused by not understanding the
implications of alignment and the use of placement new.
--

Bill Seurer     ID Tools and Compiler Development      IBM Rochester, MN
BillSeurer@vnet.ibm.com                            BillSeurer AT aol.com
http://members.aol.com/BillSeurer  (replace " AT " with "@" to email me)
For the SPAMers: iuko@pliz.com mlyh@k04c.com r2tc@w701.com qt1v@y697.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                             ]