Topic: Alignment


Author: Christopher Eltschka <celtschk@web.de>
Date: Wed, 19 Dec 2001 14:13:35 GMT
Raw View
Attila Feher <Attila.Feher@lmf.ericsson.se> writes:

[...]

> BTW, along with this, I was thinking to suggest a little addition to the
> language (which the compilers could easily do).  It would be nice to be
> able to tell (esp. for such char arrays), that it should be aligned as
> type T.  Something like (syntax I have no idea about, so I follow an
> xBase like one for fun :-):
>
> class T ...
> ...
> char arr[sizeof(T)*100] align as T;
>
> This could be used to create non-allocating, maximized capacity
> sequential containers purely on the stack (or as globals for the brave
> :-).

I'd prefer a simpler solution:

Define a type align, which is a complete POD type with an alignment so
it's always correctly aligned for any type, and it's size shall be the
smallest size possible to fulfill this requirement (i.e. sizeof align
gives the maximum alignment).

This could be used to align arrays like

union
{
  align dummy;
  unsigned char data[1000]; // array perfectly aligned for any type
};

unsigned char* p = data + 3*sizeof align;
  // p is also perfectly aligned

int* i = new(p) int; // guaranteed to work
                     // (unless 3*sizeof align + sizeof int > 1000)

Except for sizeof and operator=, there need not be any operator
defined for align.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Wed, 5 Dec 2001 16:50:59 GMT
Raw View
Ron Natalie  wrote:
>
>
> Valentin Bonnard wrote:
>>=20
>> The standard doesn't define the word alignment, so the answer
>> to any standard question about alignment is basically ``mu=B4=B4.
>
> Incorrect.

Actually, it defines the term but doesn't use it. (That's
the C++ way: define terms nobody use, refrain from defining
terms that are used.)

> The word alignment is defined in 3.9p5:
>
>   The alignment of a complete object type is an
>   implementation-defined integer value representing=20
>   a number of bytes; an object is allocated at an address
>   that meets the alignment requirements of its object type.

``Alignement'' is defined but not used. OTOH, ``alignment
requirements'' isn't defined.

> Further, it is also defined in the C standard as:
>
> 3.1 alignment A requirement that objects of a particular type=20
>     be located on storage boundaries
>     with addresses that are particular multiples ot a byte address

At least the C+++ definition, if useless, made sens. The C
definition seems to think that an address is an integer.

Conclusion: these two standard fail to define alignment in
any meaningfull ways.

  --   VB

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 3 Dec 2001 17:51:25 GMT
Raw View
Attila Feher wrote:
>
> Niklas Matthies wrote:
> [SNIP]
> > 0 is not an address. It's a null pointer value, and performing address
> > arithmetics with it invokes undefined behavior.
>
> Opps.  Could you point me to a section number in the standard what
> actually says that?  I am not questioning your judgement.  I just would
> like to see it, and it is way too huge (still) for me to easily find
> things. :-(

First, a correction: replace 'address' with 'pointer' in Niklas'
statement. An address is a concept that matters to the machine, but the
corresponding C concept is a pointer. A pointer typically contains the
address of the thing it points at, but it's also legal for it to contain
other information as well. A pointer needn't carry the address in any
easily-decoded fashion, either: the bits could be rotated, or the bytes
flipped, or it might contain an index into a lookup table that contains
the actual address.

Secondly, a null pointer CAN be an actual address. There have been real
machines where it did point to the start of memory, leading to people to
have the same expectations you've expressed. There have even been
implementations where *(int*)0 was safe, and guaranteed to return a 0,
which misled people even more grievously.

6.3.2.3p3 guarantees that a null pointer "is guaranteed to compare
unequal to a pointer to any object or function". Note that in order to
safely dereference a pointer, it must point at an object (or a function,
depending upon it's type).

According to 6.5.9p6,
"Two pointers compare equal if and only if both are null pointers, both
are pointers to the same object (including a pointer to an object and a
subobject at its beginning) or function, both are pointers to one past
the last element of the same array object, or one is a pointer to one
past the end of one array object and the other is a pointer to the start
of a different array object that happens to immediately follow the first
array object in the address space."

Therefore, a null pointer is guaranteed not to point to any object or
function, since if it did, 6.5.9p6 would require it to compare equal to
any such pointer, contradicting 6.3.2.3p3. However, 6.3.2.3p3 does not
prohibit null pointers from comparing equal to pointers one past the end
of an object, so a null pointer could point to such a location.
Therefore, the following code does not necessarily work the way that the
comments suggest:

void func(const char *start, const char *end)
{
 char *p;

 if(end==NULL)
 {
  // treat as null-terminated string.
  for(p=start; *p; p++)
   /* do something */;
 }else{
  // Use 'end' to terminate loop
  for(p=start; p<end; p++)
   /* do something else */;
 }
}

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Mon, 3 Dec 2001 17:55:09 GMT
Raw View
The standard doesn't define the word alignment, so the answer
to any standard question about alignment is basically ``mu      .

  --   VB

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Mon, 3 Dec 2001 17:55:16 GMT
Raw View
Attila Feher  wrote:

> OK, I just did a ptrdiff, on an address yesterday (just before writing
> this) and it was _negative_.  As a result of:
> char array_[10];
> ...
> ... array_-static_cast<char*>(0)
>
> The result was negative.  Which is a lie.

No.

> Since the address 0 is _not_
> after the address of the member variable named array_.

0 isn't a pointer, it's an integer, and if you are talking about
the null pointer of the appropriate type, then no, it isn't after
or before anything. The only ordering is between members of a
structure, or elements in an array. Arbitrary complete objects
aren't ordered, and comparison between a null and a non-null
pointer isn't well-defined.

> OK, my other trick was as above.  Take the address of the variable, cast
> to char * (up to now everything should be A OK and standard) and then
> substract static_cast<char*>(0) from it.  Now I think that the result is
> supposed to be a _positive_ number, representing the _distance_ in bytes
> between the two pointers.  Since the second one is zero, the result
> should have been a positive integral value, showing exactly how many
> bytes are between address 0 and address of the variable.

It makes no sens, because there is no address 0 -- a null
pointer, by definition, isn't the address of something.

>> There's nothing in the standard that says that alignment is a function
>> of object size

Indeed, it is _not_.

  --   VB

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Michiel Salters<Michiel.Salters@cmg.nl>
Date: Mon, 3 Dec 2001 18:43:27 GMT
Raw View
In article <3C05F6F4.84361295@lmf.ericsson.se>, Attila Feher says...
>
>"James Kuyper Jr." wrote:
>[SNIP]
>> The best suggestion that has been made to cope with this problem is to
>> require every implementation to define a typedef such as std::max_align,
>> which defines a type that has exactly the maximum alignment requirement
>> that comes up in that implementation.
>
>Now I cannot really see why is it the best... but my bigger problem is,
>that I cannot really see how can this help me with aligning a character
>array inside a template on the stack?  Could you give an example?  Of
>course, I look for a (final) solution, which wastes the least possible
>number of bytes.  So if I want a maximum 3 characters (capacity) dynamic
>array on the stack, I certainly do not want it to have the 16 bytes
>alignment requirement of the __incredibly_long_double_t what the actual
>compiler may support...
>
>Attila

It is something which has been noted as something which might require
attention for the next standard.

I personally think we might require

template <typename T>
struct align_traits {
const size_t overallocation;
static T* aligned( char* );
};

such that align_trait<T>::aligned(pc) points to an array of N Ts, if
pc points to at least N*sizeof(T)+align_traits<T>::overallocation
bytes.

I think this can be done in the std::library, even on current
compilers. It might be slightly wasteful, if the compiler has problems
with specialization. They might have to use their strictest alignment.

Regards,

--
Michiel Salters
Consultant Technical Software Engineering
CMG Trade, Transport & Industry
Michiel.Salters@cmg.nl

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-01-01@nmhq.net (Niklas Matthies)
Date: Mon, 3 Dec 2001 19:16:11 GMT
Raw View
On Mon,  3 Dec 2001 17:55:09 GMT, Valentin Bonnard <Valentin.Bonnard@free.fr> wrote:
>  The standard doesn't define the word alignment,

Yes it does, in 3.9p5: "The /alignment/ of a complete object type is an
implementation-defined integer value representing a number of bytes".

It's true that this definition is only remotely helpful, though.

-- Niklas Matthies
--
Sex may be safe... love never is.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 3 Dec 2001 19:58:19 GMT
Raw View

Valentin Bonnard wrote:
>=20
> The standard doesn't define the word alignment, so the answer
> to any standard question about alignment is basically ``mu=B4=B4.

Incorrect.  The word alignment is defined in 3.9p5:

  The alignment of a complete object type is an
  implementation-defined integer value representing=20
  a number of bytes; an object is allocated at an address
  that meets the alignment requirements of its object type.

Further, it is also defined in the C standard as:

3.1 alignment A requirement that objects of a particular type=20
    be located on storage boundaries
    with addresses that are particular multiples ot a byte address

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 4 Dec 2001 18:33:33 GMT
Raw View
Ron Natalie wrote:
>=20
> Valentin Bonnard wrote:
> >
> > The standard doesn't define the word alignment, so the answer
> > to any standard question about alignment is basically ``mu=B4=B4.
>=20
> Incorrect.  The word alignment is defined in 3.9p5:
>=20
>   The alignment of a complete object type is an
>   implementation-defined integer value representing
>   a number of bytes; an object is allocated at an address
>   that meets the alignment requirements of its object type.

That's not really a proper definition.

> Further, it is also defined in the C standard as:
>=20
> 3.1 alignment A requirement that objects of a particular type
>     be located on storage boundaries
>     with addresses that are particular multiples ot a byte address

I believe that, unfortunately, the inadequate definition of alignment in
the C++ standard, "hides" the more useful definition given in the C
standard.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 4 Dec 2001 18:33:24 GMT
Raw View
Niklas Matthies wrote:
>
> On Fri, 30 Nov 2001 04:51:50 GMT, James Kuyper Jr. <kuyper@wizard.net> wrote:
> >  Niklas Matthies wrote:
> >  ...
> > > There is pretty simple method to determine the alignment requirement of
> > > a type T:
> > >
> > >    struct X { char c; T t; };
> > >
> > >    const size_t T_min_alignment = offsetof(X, t);
> > >
> > > Now whenever you have a memory position p known to be properly aligned
> > > for T, then p + n * T_min_alignment will be properly aligned for T as
> > > well for any n (as long as it's still within the allocated space).
> >
> >  Your technique assumes that an implementation will use the smallest
> >  amount of padding that is consistent with alignment requirements.
>
> Not at all. I'm not claiming that the determined value is the minimum
> alignement requirement, but just some alignment requirement which
> happens to be a reasonable one on reasonable implementations and that
> the program can use as a minimum alignment value for the given type.

You labelled it T_min_alignement; if it's not intended to store the
minimum alignment requirement, I'd recommend a change in name.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-01-01@nmhq.net (Niklas Matthies)
Date: Tue, 4 Dec 2001 19:03:47 GMT
Raw View
On Tue,  4 Dec 2001 18:33:24 GMT, James Kuyper Jr. <kuyper@wizard.net> wrote:
>  Niklas Matthies wrote:
> > On Fri, 30 Nov 2001 04:51:50 GMT, James Kuyper Jr. <kuyper@wizard.net> wrote:
> > >  Niklas Matthies wrote:
> > >  ...
> > > > There is pretty simple method to determine the alignment requirement of
> > > > a type T:
> > > >
> > > >    struct X { char c; T t; };
> > > >
> > > >    const size_t T_min_alignment = offsetof(X, t);
> > > >
> > > > Now whenever you have a memory position p known to be properly aligned
> > > > for T, then p + n * T_min_alignment will be properly aligned for T as
> > > > well for any n (as long as it's still within the allocated space).
> > >
> > >  Your technique assumes that an implementation will use the smallest
> > >  amount of padding that is consistent with alignment requirements.
> >
> > Not at all. I'm not claiming that the determined value is the minimum
> > alignement requirement, but just some alignment requirement which
> > happens to be a reasonable one on reasonable implementations and that
> > the program can use as a minimum alignment value for the given type.
>
>  You labelled it T_min_alignement; if it's not intended to store the
>  minimum alignment requirement,

That's why it wasn't named "T_min_alignement_requirement_as_imposed_by_
the_implementation". For the code, the value of the constant is simply
the minimum alignment to be used for placing objects of type T into
memory "by hand". It's true that the code may stumble across objects of
type T placed in memory by the implementation with an alignment smaller
than T_min_alignement, but since there's no way to portably tell, this
should't matter.

Another issue is, if the implementation where required to define such a
constant, would it really be useful for the constant to hold the actual
minimum, even if accesses to accordingly-aligned objects may be much
slower than to stricter-aligned objects?
We may need both least_alignement<T> and fast_alignment<T>, after all.

> I'd recommend a change in name.

You're welcome. :)

-- Niklas Matthies
--
Sex may be safe... love never is.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Ron Natalie <ron@sensor.com>
Date: Thu, 29 Nov 2001 17:59:31 GMT
Raw View

"James
> ...
> > There's nothing in the standard that says that alignment is a function
> > of object size (although I've never seen an implementation where multiples
> > of the object size weren't safe, frequently other values are aligned as
> > well).
>
> The rules governing arrays imply that sizeof(T) must be an integer
> multiple of the alignement requirement of T.

No it doesn't.  It just says that sizeof(T) added from one suitably
aligned T must get you to another suitably aligned T.  It doesn't
say anything about the modulo of the actual address.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-01-01@nmhq.net (Niklas Matthies)
Date: Thu, 29 Nov 2001 18:00:07 GMT
Raw View
On Thu, 29 Nov 2001 17:30:26 GMT, Attila Feher <Attila.Feher@lmf.ericsson.se> wrote:
>  Ron Natalie wrote:
> > Attila Feher wrote:
> >
> > > Is it sure that size_t and ptrdiff_t has the same "size", so like the
> > > diff is the signed "pair" of the size_t?
> >
> > Well ptrdiff_t is signed, size_t is unsigned.  However, I can't imagine
> > any way that an implementation would work that would allow a legal
> > value of sizeof's return from not fitting in a ptrdiff_t nor a legal
> > result of pointer subtraction from fitting in a size_t.
>
>  OK, I just did a ptrdiff, on an address yesterday (just before writing
>  this) and it was _negative_.  As a result of:
>  char array_[10];
>  ...
>  ... array_-static_cast<char*>(0)
>
>  The result was negative.  Which is a lie.  Since the address 0 is _not_
>  after the address of the member variable named array_.

0 is not an address. It's a null pointer value, and performing address
arithmetics with it invokes undefined behavior.

-- Niklas Matthies
--
knowledge, n.:  Things you believe.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-01-01@nmhq.net (Niklas Matthies)
Date: Thu, 29 Nov 2001 18:09:03 GMT
Raw View
On Thu, 29 Nov 2001 16:43:25 GMT, Attila Feher <Attila.Feher@lmf.ericsson.se> wrote:
>  "James Kuyper Jr." wrote:
>  [SNIP]
> > The best suggestion that has been made to cope with this problem is to
> > require every implementation to define a typedef such as std::max_align,
> > which defines a type that has exactly the maximum alignment requirement
> > that comes up in that implementation.
>
>  Now I cannot really see why is it the best... but my bigger problem is,
>  that I cannot really see how can this help me with aligning a character
>  array inside a template on the stack?  Could you give an example?  Of
>  course, I look for a (final) solution, which wastes the least possible
>  number of bytes.  So if I want a maximum 3 characters (capacity) dynamic
>  array on the stack, I certainly do not want it to have the 16 bytes
>  alignment requirement of the __incredibly_long_double_t what the actual
>  compiler may support...

There is pretty simple method to determine the alignment requirement of
a type T:

   struct X { char c; T t; };

   const size_t T_min_alignment = offsetof(X, t);

Now whenever you have a memory position p known to be properly aligned
for T, then p + n * T_min_alignment will be properly aligned for T as
well for any n (as long as it's still within the allocated space).

There's no portable way, though, to find such a p within a character
array whose alignment is not known.

-- Niklas Matthies
--
When you laugh, the world ignores you. Crying doesn't help either.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Ron Natalie <ron@sensor.com>
Date: Thu, 29 Nov 2001 18:31:10 GMT
Raw View

Niklas Matthies wrote:
>
> On Thu, 29 Nov 2001 16:43:25 GMT, Attila Feher <Attila.Feher@lmf.ericsson.se> wrote:
> >
> There is pretty simple method to determine the alignment requirement of
> a type T:
>
>    struct X { char c; T t; };
>
>    const size_t T_min_alignment = offsetof(X, t);

Cool, I like it.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 30 Nov 2001 04:51:50 GMT
Raw View
Niklas Matthies wrote:
...
> There is pretty simple method to determine the alignment requirement of
> a type T:
>
>    struct X { char c; T t; };
>
>    const size_t T_min_alignment = offsetof(X, t);
>
> Now whenever you have a memory position p known to be properly aligned
> for T, then p + n * T_min_alignment will be properly aligned for T as
> well for any n (as long as it's still within the allocated space).

Your technique assumes that an implementation will use the smallest
amount of padding that is consistent with alignment requirements. That's
reasonable, but it's  quite legal for an implementation to use a larger
amount of padding. I've seen implementations where where it was possible
to place doubles with any arbitrary alignement. That means that the
alignment requirement was exactly 1. However, doubles placed at even
addresses were more efficient, so in many contexts (such as struct
layouts) it forced them to even addresses. Your approach would give an
incorrect value of '2' under that implementation.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 30 Nov 2001 17:32:12 GMT
Raw View
Attila Feher wrote:
> Ron Natalie wrote:
...
> OK, I just did a ptrdiff, on an address yesterday (just before writing
> this) and it was _negative_.  As a result of:
> char array_[10];
> ...
> ... array_-static_cast<char*>(0)
>
> The result was negative.  Which is a lie.  Since the address 0 is _not_
> after the address of the member variable named array_.

It's not necessarily a lie. The standard says nothing about the relative
relative order of static_cast<T*>(0) and any other pointer. I've used
platforms where all valid pointers converted to negative numbers.

> > any meaning when converted back to a pointer.  Nothing says that the
> > conversion form arbitrary pointer to int has any particular format.
>
> I do not convert it back to pointer.  All I wanted is modulus with
> sizeof.

Exactly. Converting that number back to a pointer is the ONLY thing that
has a standard-defined meaning. It's a number, so you can do arithmetic
on it, but that arithmetic has no special meaning. This is just like the
fact that it's not meaningful to divide a phone number by 2, or to add 5
to an IP address.

...
> ways.  However I wonder how was it possible to overlook it that
> ptrdiff_t returned by a pointer operation a-b should be _only_ negative
> if the address b is _after_ the address a...  Because that would help a
> lot to portably convert an address to an integral type.

Not really. The only context where the standard says anything about the
relative order of pointers is when they point to two parts of the same
object. The standard says nothing about the relative order of the
addresses stored in pointers, nor of the relative order of pointers
which are cast to integers; the only thing it defines is the relative
order of pointers themselves.

> OK, my other trick was as above.  Take the address of the variable, cast
> to char * (up to now everything should be A OK and standard) and then
> substract static_cast<char*>(0) from it.  Now I think that the result is
> supposed to be a _positive_ number, representing the _distance_ in bytes
> between the two pointers.  Since the second one is zero, the result
> should have been a positive integral value, showing exactly how many
> bytes are between address 0 and address of the variable.

That's plausible, but there's nothing in the standard that supports your
suppositions.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 30 Nov 2001 17:32:16 GMT
Raw View
Ron Natalie wrote:
>
> "James
...
> > The rules governing arrays imply that sizeof(T) must be an integer
> > multiple of the alignement requirement of T.
>
> No it doesn't.  It just says that sizeof(T) added from one suitably
> aligned T must get you to another suitably aligned T.  It doesn't
> say anything about the modulo of the actual address.

Agreed. The standard's definition of 'alignement' is exceedingly vague.
It says that the alignment is a number, but it doesn't actually say what
that number means. I tend to forget about that, and assume a fairly
conventional definition of 'alignement'. I "know" what 'alignment'
actually means, and so do many other programmers, even if the standard
is coy about it. And using that conventional definition, the fact that
an array of T must be contiguous and have no padding between it's
elements DOES imply that sizeof(T) is a multiple of the alignement
requirement of T. However, since the standard does not meaningfully
define 'alignement', you actually can't say much of anything useful
about it.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Attila Feher <Attila.Feher@lmf.ericsson.se>
Date: Fri, 30 Nov 2001 19:28:49 GMT
Raw View
Niklas Matthies wrote:
[SNIP]
> 0 is not an address. It's a null pointer value, and performing address
> arithmetics with it invokes undefined behavior.

Opps.  Could you point me to a section number in the standard what
actually says that?  I am not questioning your judgement.  I just would
like to see it, and it is way too huge (still) for me to easily find
things. :-(

A

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Attila Feher <Attila.Feher@lmf.ericsson.se>
Date: Fri, 30 Nov 2001 19:28:55 GMT
Raw View
"James Kuyper Jr." wrote:
[SNIP]
> > ... array_-static_cast<char*>(0)
> >
> > The result was negative.  Which is a lie.  Since the address 0 is _not_
> > after the address of the member variable named array_.
>
> It's not necessarily a lie. The standard says nothing about the relative
> relative order of static_cast<T*>(0) and any other pointer. I've used
> platforms where all valid pointers converted to negative numbers.

I see, but _difference_ in the name of the type suggests that it is
really the _difference_ or _distance_ between those 2.  And it isn't.
:-(((

> > > any meaning when converted back to a pointer.  Nothing says that the
> > > conversion form arbitrary pointer to int has any particular format.
> >
> > I do not convert it back to pointer.  All I wanted is modulus with
> > sizeof.
>
> Exactly. Converting that number back to a pointer is the ONLY thing that
> has a standard-defined meaning. It's a number, so you can do arithmetic
> on it, but that arithmetic has no special meaning. This is just like the
> fact that it's not meaningful to divide a phone number by 2, or to add 5
> to an IP address.

Got it! :-)))

> > ways.  However I wonder how was it possible to overlook it that
> > ptrdiff_t returned by a pointer operation a-b should be _only_ negative
> > if the address b is _after_ the address a...  Because that would help a
> > lot to portably convert an address to an integral type.
>
> Not really. The only context where the standard says anything about the
> relative order of pointers is when they point to two parts of the same
> object. The standard says nothing about the relative order of the
> addresses stored in pointers, nor of the relative order of pointers
> which are cast to integers; the only thing it defines is the relative
> order of pointers themselves.

OK.  But if I take a biga biga array (I have heard that biga biga from a
humorist, who wanted a fork on his table :-) and I say
&array[veeerybignumber-]&array[0] I would assume I will get a number,
which give me the _bytes_ between those two!  A _positive_ number.
Where do I fail in this thinking?

[SNIP]
> That's plausible, but there's nothing in the standard that supports your
> suppositions.

I was afraid of that.

Attila

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Adam Peterson <ahp6@email.byu.edu>
Date: Fri, 30 Nov 2001 19:49:04 GMT
Raw View
> OK.  But if I take a biga biga array (I have heard that biga biga from a
> humorist, who wanted a fork on his table :-) and I say
> &array[veeerybignumber-]&array[0] I would assume I will get a number,
> which give me the _bytes_ between those two!  A _positive_ number.
> Where do I fail in this thinking?

I assume you mean (&array[veeerybignumber] - &array[0]).  In this case, you
will simply get veeerybignumber - 0, or veeerybignumber.  This is standard
pointer arithmetic.  (This also assumes that array has more than
veeerybignumber elements, or you're jumping off the end of the array and
invoking undefined behavior.)

Adam Peterson


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Ron Natalie <ron@sensor.com>
Date: Fri, 30 Nov 2001 20:17:41 GMT
Raw View

Attila Feher wrote:
>
> Niklas Matthies wrote:
> [SNIP]
> > 0 is not an address. It's a null pointer value, and performing address
> > arithmetics with it invokes undefined behavior.
>
> Opps.  Could you point me to a section number in the standard what
> actually says that?  I am not questioning your judgement.  I just would
> like to see it, and it is way too huge (still) for me to easily find
> things. :-(
>
Point us to a section that says it is an address?  The standard
leaves the formatting of pointers up to the implementation.  The
notion of addressing is outside the language.

0 is the null pointer constant, a funky thing that when converted to
a pointer type yields a null pointer.  The standard doesn't say anything
about the null pointer other than the fact that it is distinct from
a pointer to any object and that the it be recognized as being a null
pointer in several contexts.  WHat the null pointer value ends up
being is again an implementation issue.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Sat, 1 Dec 2001 01:01:18 GMT
Raw View
Attila Feher wrote:
>
> "James Kuyper Jr." wrote:
> [SNIP]
> > > ... array_-static_cast<char*>(0)
> > >
> > > The result was negative.  Which is a lie.  Since the address 0 is _not_
> > > after the address of the member variable named array_.
> >
> > It's not necessarily a lie. The standard says nothing about the relative
> > relative order of static_cast<T*>(0) and any other pointer. I've used
> > platforms where all valid pointers converted to negative numbers.
>
> I see, but _difference_ in the name of the type suggests that it is
> really the _difference_ or _distance_ between those 2.  And it isn't.
> :-(((

It is the difference (or distance) between two pointers, when it's legal
to subtract them. You can only legally subtract two pointers when they
both point into (or one element past the end of) the same object. A null
pointer NEVER points at an object, and cannot be portably guaranteed to
be one past the end of any object, much less any particular object. The
distance between pointers into distinct objects is undefined by the C
standard.

...
> > Not really. The only context where the standard says anything about the
> > relative order of pointers is when they point to two parts of the same

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > object. The standard says nothing about the relative order of the
> > addresses stored in pointers, nor of the relative order of pointers
> > which are cast to integers; the only thing it defines is the relative
> > order of pointers themselves.
>
> OK.  But if I take a biga biga array (I have heard that biga biga from a
> humorist, who wanted a fork on his table :-) and I say
> &array[veeerybignumber-]&array[0] I would assume I will get a number,
> which give me the _bytes_ between those two!  A _positive_ number.
> Where do I fail in this thinking?

I assume you meant this:

 &array[veeerybignumber]-&array[0]

If so, that depends entirely upon the value of 'veeerybignumber'. If
it's greater than or equal to (sizeof array/sizeof array[0]), then
array[veeerybignumber] is a constraint violation, which can cause your
computer to crash. Otherwise, the subtraction is legal, and the
guaranteed result of that subtraction is the value of 'verrybignumber',
converted to ptrdiff_t. That will be the number of bytes, if
sizeof(array[0]) is 1.

However, this is absolutely useless for setting up absolute addressing,
since you can't legally extend it outside the range of 'array'.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-01-01@nmhq.net (Niklas Matthies)
Date: Sat, 1 Dec 2001 22:24:42 GMT
Raw View
On Fri, 30 Nov 2001 19:28:49 GMT, Attila Feher <Attila.Feher@lmf.ericsson.se> wrote:
>  Niklas Matthies wrote:
>  [SNIP]
> > 0 is not an address. It's a null pointer value, and performing address
> > arithmetics with it invokes undefined behavior.
>
>  Opps.  Could you point me to a section number in the standard what
>  actually says that?  I am not questioning your judgement.  I just would
>  like to see it, and it is way too huge (still) for me to easily find
>  things. :-(

Pointer arithmetics (5.7) is only defined for pointer values pointing
into (or right behind) an array object, and the null pointer value
(4.10) is not defined to point at any object. Moreover, the behavior of
substracting one pointer from another is only defined if the pointers
point into (or right behind) the same array (5.7p7).

-- Niklas Matthies
--
Less matters that which you can take by yourself than that which others
have given to you.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-01-01@nmhq.net (Niklas Matthies)
Date: Mon, 3 Dec 2001 17:51:38 GMT
Raw View
On Fri, 30 Nov 2001 04:51:50 GMT, James Kuyper Jr. <kuyper@wizard.net> wrote:
>  Niklas Matthies wrote:
>  ...
> > There is pretty simple method to determine the alignment requirement of
> > a type T:
> >
> >    struct X { char c; T t; };
> >
> >    const size_t T_min_alignment = offsetof(X, t);
> >
> > Now whenever you have a memory position p known to be properly aligned
> > for T, then p + n * T_min_alignment will be properly aligned for T as
> > well for any n (as long as it's still within the allocated space).
>
>  Your technique assumes that an implementation will use the smallest
>  amount of padding that is consistent with alignment requirements.

Not at all. I'm not claiming that the determined value is the minimum
alignement requirement, but just some alignment requirement which
happens to be a reasonable one on reasonable implementations and that
the program can use as a minimum alignment value for the given type.

-- Niklas Matthies
--
Light travels faster than sound. This is why some people appear bright
until you hear them speak.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Attila Feher <Attila.Feher@lmf.ericsson.se>
Date: Wed, 28 Nov 2001 18:07:18 GMT
Raw View
Are there any "rules" of alignment in the definition of C++?

To be more concrete:

Is it sure that size_t and ptrdiff_t has the same "size", so like the
diff is the signed "pair" of the size_t?

Is it "sure" that the conceptual address 0 is properly aligned for all
types?

Is it safe (portable, well defined) to cast a pointer (like char *, void
*) to size_t and make calculations (like modulus) with it?

Can I say that given an array of chars and any type T:

char array[sizeof(T)+sizeof(T)-1];

I can "align" a type T (for operator new) into this array by the
following code?

char *startpos=array+((size_t)&array%sizeof(T));

I mean is it portable?  It "asks" 2 questions:

Is it well defined to cast a pointer to size_t?  Is it true for all
supported architectures that the conceptual address 0 is well aligned
for all types?  (Since I "pad" my array up to the first T boundary
counting from (char *)0.)

BTW, along with this, I was thinking to suggest a little addition to the
language (which the compilers could easily do).  It would be nice to be
able to tell (esp. for such char arrays), that it should be aligned as
type T.  Something like (syntax I have no idea about, so I follow an
xBase like one for fun :-):

class T ...
...
char arr[sizeof(T)*100] align as T;

This could be used to create non-allocating, maximized capacity
sequential containers purely on the stack (or as globals for the brave
:-).

Attila

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Ron Natalie <ron@sensor.com>
Date: Wed, 28 Nov 2001 19:12:31 GMT
Raw View

Attila Feher wrote:

> Is it sure that size_t and ptrdiff_t has the same "size", so like the
> diff is the signed "pair" of the size_t?

Well ptrdiff_t is signed, size_t is unsigned.  However, I can't imagine
any way that an implementation would work that would allow a legal
value of sizeof's return from not fitting in a ptrdiff_t nor a legal
result of pointer subtraction from fitting in a size_t.

> Is it safe (portable, well defined) to cast a pointer (like char *, void
> *) to size_t and make calculations (like modulus) with it?

NO!  size_t needs only be big enough to hold the maximum size in bytes
of the larges legally creatable object.  A pointer might be LARGER.
The rules on mucking with pointer to integer conversions via reinterpret
cast require that the integer be "suitably large".  Furthermore, there's
no guarantee that if you change it while it is an integer that it has
any meaning when converted back to a pointer.  Nothing says that the
conversion form arbitrary pointer to int has any particular format.

I can think of at least one implemenation I used that was a word addressed
machine and the byte offset in a char* were in the high order bits.
You could not cast to int and play those math games even ignoring
the alignment issues.

> Can I say that given an array of chars and any type T:
>
> char array[sizeof(T)+sizeof(T)-1];
>
> I can "align" a type T (for operator new) into this array by the
> following code?
>
> char *startpos=array+((size_t)&array%sizeof(T));
>
> I mean is it portable?

No.

> Is it well defined to cast a pointer to size_t?

No, for reasons I gave above.  And even if it were, the math you do and
the conversion back is very much IMPLEMENTATION SPECIFIC.

> Is it true for all
> supported architectures that the conceptual address 0 is well aligned
> for all types?  (Since I "pad" my array up to the first T boundary
> counting from (char *)0.)

There's nothing in the standard that says that alignment is a function
of object size (although I've never seen an implementation where multiples
of the object size weren't safe, frequently other values are aligned as
well).

However, if I understand what you are trying to do.  The traditional kludge
is to use a union with all the things likely to have alignment issues:

 union Aligned {
    char hunk_o_memory[hunk_size];
    int  i;
    long l;
    float f;
    double d;
    long double ld;
    void* vp;
 };

The presence of the various types causes the union to be located such that the
alignement for all of them is guranteed.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 28 Nov 2001 22:56:04 CST
Raw View
Attila Feher wrote:
>
> Are there any "rules" of alignment in the definition of C++?

There are rules that depend upon alignment, but alignment requirements
are at the discretion of the implementor.

> To be more concrete:
>
> Is it sure that size_t and ptrdiff_t has the same "size", so like the
> diff is the signed "pair" of the size_t?

No.

> Is it "sure" that the conceptual address 0 is properly aligned for all
> types?

No. The only addresses that are guaranteed to be properly aligned for
all types, are those returned by allocation functions, such as malloc()
and operator new().

The addresses returned by new-expressions for arrays of character type
have some alignment guarantees, but they're not quite as strict. They
are guaranteed to be suitably aligned for the strictest alignment
requirement of any object that can fit in the array. That's not quite as
useful as it may seem (nor as useful as it was intended to be). The
arrays are not guaranteed to be aligned for any other type, whether or
not that type will fit in the array, and there's no way to find out what
that strictest alignment requirement is. However, most systems have
alignment requirements that are all powers of two, in which case there's
no problem.

The standard has no concept that corresponds precisely to "conceptual
address 0". The two things that come closest are (T*)0 and a pointer
with all bits set to 0. (T*) has a limited number of interesting
guarantees associated with it; but suitable alignement for an object of
arbitrary type is not one of them. A pointer whose bits are all 0 is not
even guaranteed to be a valid pointer.

> Is it safe (portable, well defined) to cast a pointer (like char *, void
> *) to size_t and make calculations (like modulus) with it?

Yes, it's safe. However, the results are implementation-defined. The
results of those calculations have no meaning that's guaranteed by the
standard. They may have an implementation-defined meaning.

> Can I say that given an array of chars and any type T:
>
> char array[sizeof(T)+sizeof(T)-1];

Yes.

> I can "align" a type T (for operator new) into this array by the
> following code?
>
> char *startpos=array+((size_t)&array%sizeof(T));

That calculation is legal, but doesn't actually guarantee that startpos
is properly aligned to store an object of type T.

> I mean is it portable?  It "asks" 2 questions:
>
> Is it well defined to cast a pointer to size_t?  Is it true for all

No. It's implementation defined. What the result means is entirely up to
the implementation.

...
> BTW, along with this, I was thinking to suggest a little addition to the
> language (which the compilers could easily do).  It would be nice to be
> able to tell (esp. for such char arrays), that it should be aligned as
> type T.  Something like (syntax I have no idea about, so I follow an
> xBase like one for fun :-):
...

The best suggestion that has been made to cope with this problem is to
require every implementation to define a typedef such as std::max_align,
which defines a type that has exactly the maximum alignment requirement
that comes up in that implementation.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 29 Nov 2001 16:43:07 GMT
Raw View
Ron Natalie wrote:
>
> Attila Feher wrote:
...
> Well ptrdiff_t is signed, size_t is unsigned.  However, I can't imagine
> any way that an implementation would work that would allow a legal
> value of sizeof's return from not fitting in a ptrdiff_t nor a legal
> result of pointer subtraction from fitting in a size_t.

As a practical matter, you're right. However, the standard doesn't
guaranteeit.

...
> There's nothing in the standard that says that alignment is a function
> of object size (although I've never seen an implementation where multiples
> of the object size weren't safe, frequently other values are aligned as
> well).

The rules governing arrays imply that sizeof(T) must be an integer
multiple of the alignement requirement of T.

...
> However, if I understand what you are trying to do.  The traditional kludge
> is to use a union with all the things likely to have alignment issues:
>
>         union Aligned {
>            char hunk_o_memory[hunk_size];
>            int  i;
>            long l;
>            float f;
>            double d;
>            long double ld;
>            void* vp;
>         };
>
> The presence of the various types causes the union to be located such that the
> alignement for all of them is guranteed.

However, there's no list of finite length that covers all possible
alignement issues. This technique is most appropriate if there's a
finite list of types that actually matter for a give application.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Attila Feher <Attila.Feher@lmf.ericsson.se>
Date: Thu, 29 Nov 2001 16:43:25 GMT
Raw View
"James Kuyper Jr." wrote:
[SNIP]
> The best suggestion that has been made to cope with this problem is to
> require every implementation to define a typedef such as std::max_align,
> which defines a type that has exactly the maximum alignment requirement
> that comes up in that implementation.

Now I cannot really see why is it the best... but my bigger problem is,
that I cannot really see how can this help me with aligning a character
array inside a template on the stack?  Could you give an example?  Of
course, I look for a (final) solution, which wastes the least possible
number of bytes.  So if I want a maximum 3 characters (capacity) dynamic
array on the stack, I certainly do not want it to have the 16 bytes
alignment requirement of the __incredibly_long_double_t what the actual
compiler may support...

Attila

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Attila Feher <Attila.Feher@lmf.ericsson.se>
Date: Thu, 29 Nov 2001 17:30:26 GMT
Raw View
Ron Natalie wrote:
>
> Attila Feher wrote:
>
> > Is it sure that size_t and ptrdiff_t has the same "size", so like the
> > diff is the signed "pair" of the size_t?
>
> Well ptrdiff_t is signed, size_t is unsigned.  However, I can't imagine
> any way that an implementation would work that would allow a legal
> value of sizeof's return from not fitting in a ptrdiff_t nor a legal
> result of pointer subtraction from fitting in a size_t.

OK, I just did a ptrdiff, on an address yesterday (just before writing
this) and it was _negative_.  As a result of:
char array_[10];
...
... array_-static_cast<char*>(0)

The result was negative.  Which is a lie.  Since the address 0 is _not_
after the address of the member variable named array_.

> > Is it safe (portable, well defined) to cast a pointer (like char *, void
> > *) to size_t and make calculations (like modulus) with it?
>
> NO!  size_t needs only be big enough to hold the maximum size in bytes
> of the larges legally creatable object.  A pointer might be LARGER.

That is what I have thought. :-(

> any meaning when converted back to a pointer.  Nothing says that the
> conversion form arbitrary pointer to int has any particular format.

I do not convert it back to pointer.  All I wanted is modulus with
sizeof.

> I can think of at least one implemenation I used that was a word addressed
> machine and the byte offset in a char* were in the high order bits.
> You could not cast to int and play those math games even ignoring
> the alignment issues.

Point taken.  You are right if the conversion is not defined in any
ways.  However I wonder how was it possible to overlook it that
ptrdiff_t returned by a pointer operation a-b should be _only_ negative
if the address b is _after_ the address a...  Because that would help a
lot to portably convert an address to an integral type.

[SNIP]
> > char *startpos=array+((size_t)&array%sizeof(T));
> >
> > I mean is it portable?
>
> No.
>
> > Is it well defined to cast a pointer to size_t?
>
> No, for reasons I gave above.  And even if it were, the math you do and
> the conversion back is very much IMPLEMENTATION SPECIFIC.


OK, my other trick was as above.  Take the address of the variable, cast
to char * (up to now everything should be A OK and standard) and then
substract static_cast<char*>(0) from it.  Now I think that the result is
supposed to be a _positive_ number, representing the _distance_ in bytes
between the two pointers.  Since the second one is zero, the result
should have been a positive integral value, showing exactly how many
bytes are between address 0 and address of the variable.

[SNIP]
> There's nothing in the standard that says that alignment is a function
> of object size (although I've never seen an implementation where multiples
> of the object size weren't safe, frequently other values are aligned as
> well).

OK/

> However, if I understand what you are trying to do.  The traditional kludge
> is to use a union with all the things likely to have alignment issues:
>
>         union Aligned {
>            char hunk_o_memory[hunk_size];
>            int  i;
>            long l;
>            float f;
>            double d;
>            long double ld;
>            void* vp;
>         };
>
> The presence of the various types causes the union to be located such that the
> alignement for all of them is guranteed.

Great.  But I guess noone will pad all these when need a maximum 5
characters array with dynamic size. :-(  Which I would like to get from
the same template.  Or let's say 3 integers array.  That one above is
around 10(?) integers. :-(  Not to mention that it is not self evident
why is it there. :-(  OK, I just mentioned it. :-)  I need to mention
that it is not "compiler friendly" either!  Why?  Simple.  The compiler
might have introduced an extension to the standard.  The type
__cray_vector.  Bang.  It has an alignment requirement that it should be
aligned on 8 bytes boundary, but it cannot start on addresses dividable
by 1024, and in case of full moon...  You have got it.  This structure
_only_ works, if I know _all_ the possible types my users will have.
Which is just impossible.

What I saw is that C++ compilers call nice little functions (runtime) to
make alignment when they are going construct an object.  So I see no
point why could we have a syntax, which exactly says that this character
array should be aligned as type T.  This could work in _every_
situation, without problems and make templating that on-stack-stuff
really simple:

// Absolute pesudo code, even loox like xBase
char arr_[sizeof(T)*S] aligned as T;

What syntax could be used here?  I have no idea :-(  Could it be:

char arr_[sizeof(T)*S]:T;
?

Or

auto<T> char arr_[sizeof(T)*S];
?

Attila

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Ron Natalie <ron@sensor.com>
Date: Thu, 29 Nov 2001 17:51:24 GMT
Raw View
> > Is it safe (portable, well defined) to cast a pointer (like char *, void
> > *) to size_t and make calculations (like modulus) with it?
>
> Yes, it's safe. However, the results are implementation-defined. The
> results of those calculations have no meaning that's guaranteed by the
> standard. They may have an implementation-defined meaning.

It's not even well defined to say:

 T* x = new T;

 x = (T*)(size_t) x;

There is no guarantee that size_t is a "suitably large" integral type
for the conversion.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: bkline@cortex.nlm.nih.gov (Bob Kline)
Date: 1995/10/01
Raw View
A few weeks ago, James Kanze wrote a followup to an question I posted
about whether the draft standard contained anything to support the
validity of some code from "Advanced C++" which appeared to rely on
the assumption that a static array of char would be guaranteed to
be suitably aligned for holding any data type.  In part, he wrote:

> In defence of Jim Coplien, I'm too lazy to look up the exact example,
> but from the name (LAPD), I'd guess that this is a class whose data will
> be read from or written to an external source, and which because of
> this, will only contain byte data anyway.  (LAPD is the name of the
> layer two protocol in the OSI protocol suite.)  If this is the case, his
> example should work anyway.

James:

Sorry it took me so long to respond to your hypothesis above, but
the news server at our site started dropping articles on the floor
just about the time you posted the quoted article, and I only now
came across it using the DejaNews search service.

The LAPD class contains (among other things) some pointers, which
would choke on many machines if the alignment requirements were not
satisfied.  The answers I got confirmed my suspicion that the
assumptions on which the quoted code was relying were invalid.

--
/*----------------------------------------------------------------------*/
/* Bob Kline                                       Stream International */
/* bob_kline@stream.com               formerly Corporate Software, Inc. */
/* voice: (703) 522-0820 x-311                      fax: (703) 522-5407 */
/*----------------------------------------------------------------------*/


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]