Topic: Alignment restrictions


Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/10
Raw View
Christopher Eltschka wrote:
 >
 > Maybe there should be a type align, which has the following properties:
 >
 > 1. Any valid allign object is properly alligned for each type
 > 2. sizeof(allign) is of the smallest value for which this is possible
 > 3. For any type T and any valid allign object a, (T&)a and (T*)&a are
 >    well defined, if either sizeof(T)<sizeof(allign) or a is member
 >    of an array of align and there is an n so that there are at least
 >    (n-1) allign objects after a in the array, and
 >    sizeof(T)<n*sizeof(array) (That is, there's enough memory
 >    for an object of type T). In this case, (T*)&a shall reference
 >    the same physical memory as &a. In addition, the same shall be
 >    true for (T*)(void*)&a
 >
 > I think those rules would be sufficient to declare portable
 > operator new, f.ex.:
 >
 > void* operator new(size_t size)
 > {
 >   static allign pool[10000];
 >   static allign* free=pool;
 >   void* p=free;
 >   free+=(size+sizeof(allign)-1)/sizeof(allign);
 >   return p;
 > }

If that's all you need, that could be satisfied by a
library-defined constant. Compiler vendors would be free to
define it with something as simple as:

 const int MIN_ALIGN = 8;

and the standard would merely require that they define it
somehow.

--

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: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/10
Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:

 >Christopher Eltschka wrote:
 >
 > > Maybe there should be a type align, which has the following properties:
 > >
 > > 1. Any valid allign object is properly alligned for each type
 > > 2. sizeof(allign) is of the smallest value for which this is possible
 > > 3. For any type T and any valid allign object a, (T&)a and (T*)&a are
 > >    well defined, if either sizeof(T)<sizeof(allign) or a is member
 > >    of an array of align and there is an n so that there are at least
 > >    (n-1) allign objects after a in the array, and
 > >    sizeof(T)<n*sizeof(array) (That is, there's enough memory
 > >    for an object of type T). In this case, (T*)&a shall reference
 > >    the same physical memory as &a. In addition, the same shall be
 > >    true for (T*)(void*)&a
 > >
 > > I think those rules would be sufficient to declare portable
 > > operator new, f.ex.:
 > >
 > > void* operator new(size_t size)
 > > {
 > >   static allign pool[10000];
 > >   static allign* free=pool;
 > >   void* p=free;
 > >   free+=(size+sizeof(allign)-1)/sizeof(allign);
 > >   return p;
 > > }
 >
 >If that's all you need, that could be satisfied by a
 >library-defined constant.

I don't think so.  Note that in the above example, it is important
that `pool' be correctly aligned for use as any type.  Using
`char pool[MIN_ALIGN * 10000]' wouldn't ensure that.

--
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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/10
Raw View
Paul D. DeRocco wrote:
>
> Christopher Eltschka wrote:

[...]

>  > I think those rules would be sufficient to declare portable
>  > operator new, f.ex.:
>  >

[...]

>
> If that's all you need, that could be satisfied by a
> library-defined constant. Compiler vendors would be free to
> define it with something as simple as:
>
>         const int MIN_ALIGN = 8;
>
> and the standard would merely require that they define it
> somehow.

And how would you (portably!) ensure that a pointer has this
alignment? Note that there are implementations where a pointer
is not an int (or another scalar value), so integer arithmetic
can't be applied.
---
[ 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/07
Raw View
Bill Seurer <seurer@rchland.ibm.com> wrote in article
> Hmmm.  I think you are misreading the aliasing rules.
>
> 15If  a program attempts to access the stored value of an object through
>   an lvalue of other than one of the following  types  the  behavior  is
>   undefined24):
> . . .
>   --a char or unsigned char type.
>
> So "heap + something" which is a char should be fine (barring alignment
> restrictions).

Certainly I can access T as a char, but 3.10/15 doesn't allow me to access
char as a T.  So given char heap[1000000], doing something like
   *(int*)(heap+100) = 5;
violates the letter (but not the 'alias' spirit) of 3.10/15.  I'm accessing
an array of char as an int.  3.10/15 says that is illegal.  That means I
can't write operator new which returns pointers into heap because somebody
is going to do
   (*new int) = 5;

Now there certainly may be other other problems, since heap[100] might not
be properly aligned for an int.  My point was that even without worrying
about alignment, 3.10/15 seems to be sufficient to severely restrict
portable user implementations of new.
---
[ 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/07
Raw View
Bill Wade wrote:
>
> Bill Seurer <seurer@rchland.ibm.com> wrote in article
> > Hmmm.  I think you are misreading the aliasing rules.
> >
> > 15If  a program attempts to access the stored value of an object through
> >   an lvalue of other than one of the following  types  the  behavior  is
> >   undefined24):
> > . . .
> >   --a char or unsigned char type.
> >
> > So "heap + something" which is a char should be fine (barring alignment
> > restrictions).
>
> Certainly I can access T as a char, but 3.10/15 doesn't allow me to access
> char as a T.  So given char heap[1000000], doing something like
>    *(int*)(heap+100) = 5;
> violates the letter (but not the 'alias' spirit) of 3.10/15.  I'm accessing
> an array of char as an int.  3.10/15 says that is illegal.  That means I
> can't write operator new which returns pointers into heap because somebody
> is going to do
>    (*new int) = 5;
>
> Now there certainly may be other other problems, since heap[100] might not
> be properly aligned for an int.  My point was that even without worrying
> about alignment, 3.10/15 seems to be sufficient to severely restrict
> portable user implementations of new.

Maybe there should be a type align, which has the following properties:

1. Any valid allign object is properly alligned for each type
2. sizeof(allign) is of the smallest value for which this is possible
3. For any type T and any valid allign object a, (T&)a and (T*)&a are
   well defined, if either sizeof(T)<sizeof(allign) or a is member
   of an array of align and there is an n so that there are at least
   (n-1) allign objects after a in the array, and
   sizeof(T)<n*sizeof(array) (That is, there's enough memory
   for an object of type T). In this case, (T*)&a shall reference
   the same physical memory as &a. In addition, the same shall be
   true for (T*)(void*)&a

I think those rules would be sufficient to declare portable
operator new, f.ex.:

void* operator new(size_t size)
{
  static allign pool[10000];
  static allign* free=pool;
  void* p=free;
  free+=(size+sizeof(allign)-1)/sizeof(allign);
  return p;
}
---
[ 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
Bill Seurer <seurer@rchland.ibm.com> wrote in article
<63dhmn$17uo$1@news.rchland.ibm.com>...
> In article <01bce2e4$54b12e50$2864370a@janeway>, "Bill Wade"
> <bill.wade@stoner.com> writes:
> |> At some point in this branch of the thread someone asked if the standard
> |> would be different if all mention of alignment was removed.  The answer
> |> is yes but it would be much more obviously yes (IMO) if 3.10[15] were
> |> removed.
>
> 3.10[15] doesn't directly have anything to do with alignment but is more
> concerned with aliasing.  In fact, the footnote for the section reads:
>
> "24) The intent of this list is to specify those circumstances in which
>   an object may or may not be aliased."

My point was that I can't portably write my own new() as follows:

{
  static char heap[100000000];
  return heap + something(size);
}

One reason I can't do that is because of the alignment restrictions.
Another reason I can't do that is because 3.10[15] says it is illegal to
try and use heap+something() as a T* for most kinds of T.  So if all
mention of alignment restrictions went away I still can't write new()
except in terms of malloc or the implementations new.  Aliasing is not much
of an issue here, but 3.10[15] still says this version of new isn't usable.
---
[ 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/28
Raw View
Valentin Bonnard <bonnardv@pratique.fr> wrote in article
<34520AA0.53C6@pratique.fr>...
> Bill Wade <bill.wade@stoner.com> writes:
> >From 3.10 para 15:
> >
> > "If  a program attempts to access the stored value of an object through
an
> > lvalue of other than one of the following  types  the  behavior  is
> > undefined"
>
> But my understanding is that you can't get such a lvalue, so
> this para seems useless to me. In particular, I don't why
> 'int *p = (int *) buf;' should construct a pointer of type int*
> to buf (at least in C++, the wording about reinterpret_cast
> doesn't say that).

I've removed c.s.c from the newsgroups.  I'm not at all sure C89 has
similar wording.

int a;
char b[sizeof(int)];
unsigned char* c=(unsigned char*)&a;
int* d =(int*) b;

'a' and 'b' are objects.  '*c' and '*d' are lvalues which might attempt to
access their stored values.  At least some access through *c is well
defined.  Any access through *d is undefined.  As far as I can tell access
through '*d' produces undefined behaviour because
  1) Various mentions of alignment restrictions.
  2) 3.10[15]
  3) No explicit text allowing such access.
At some point in this branch of the thread someone asked if the standard
would be different if all mention of alignment was removed.  The answer is
yes but it would be much more obviously yes (IMO) if 3.10[15] were removed.
---
[ 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                             ]