Topic: Equivalence relation
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/08 Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
>Steve Clamage wrote:
>> More generally, the C and C++ standards implicitly assume that
>> if sizeof(T1) < sizeof(T2), T1 does not have a stricter alignment
>> requirement than T2. Barry's argument shows that using a funny
>> alignment like 4*n-1 is unlikely to work.
>Really? So if you define struct S { char a[5]; };, and have
>sizeof(int)=4, the alignment of S must be at least as strict as
>the alignment on int? So if int has 4 byte alignment, S must
>have 4 byte alignment as well? (And has to add 3 padding bytes
>so that S objects can be put into arrays without holes?)
I withdraw my remark.
I remembered language from early drafts that seemed to implicitly
assume that (for example) short would not be more strictly aligned
than double. But the language seems to have been changed so as to
be neutral in that regard. At least, I couldn't find anything in
the final standard to justify my claim.
--
Steve Clamage, stephen.clamage@sun.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <david.tribble@dallas.beasys.com>
Date: 1998/12/08 Raw View
Steve Clamage wrote:
>...
> More generally, the C and C++ standards implicitly assume that
> if sizeof(T1) < sizeof(T2), T1 does not have a stricter alignment
> requirement than T2.
>...
> Machine requirements tend to be pretty straightforward. Typically,
> aligment is no stricter than the size of the object, and smaller
> objects do not have stricter requirements than larger objects.
Consider:
struct T1
{
int i;
};
struct T2
{
char c[81];
};
Type T1 has a stricter alignment requirement than type T2, even
though sizeof(T1) < sizeof(T2).
Perhaps the implicit rule you were referring to applies only to
primitive types? (After all, the alignment of all types is
inherently based on the alignments of primitive types at the lowest
level.) In that case, we only consider the alignments of T1::i and
T2::c[0] above, and the implicit rule is very probably true. It
stands to reason that a short, say, has a less strict (or at least
no more strict) alignment requirement than, say, a float. It would
be hard to present a convincing argument for the opposite.
-- David R. Tribble, dtribble@technologist.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/07 Raw View
In article <36688FC5.8C028FEB@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
>Hans Olsson wrote:
>> Distinct pointers must in this context mean that the pointers have
>> distinct values (since new[] returns a value). Loosely this can
>> be defined as: for all other pointers to objects x we have x!=i0.
>
>Those aren't distinct pointers; those are distinct pointer values. I
>think we're in agreement, however, that new[] must return distinct
>pointer values from each call (at least until one of them has ben
>released by delete[]).
new[] must of course pointers to objects such that if we manipulate one
we do not change any other valid object (that's guaranteed by
the underlying allocation function).
However, new T[0] is a special case (that should not merely call malloc(0))
and the standard makes clear that we here get a non-null pointer that
is distinct from the pointer to any other object.
>> You seem to believe that 'distinct pointers' mean that the returned
>> variable is stored at a different address than other pointers.
>
>Sort of; I think you may be misunderstanding what I mean by that. A
>pointer is an object. Distinct pointer objects are stored in different
>locations. Distinct pointer values can be stored in those distinct
>objects. However, those distinct pointer objects can also contain
>identical (or at least, equivalent) pointer values.
Of course, but the only possibility is that the 'distinct' refers
to pointer values, since no other interpretation makes sense.
>> Therefore it means that the value of returned by new T[0] is distinct
>> from the value of any other pointer to an object.
>
>It must be distinct from the value of any other pointer returned by
>previous calls to new[], which have not yet been deleted.
No, read the words:
'distinct from the pointer to any other object'.
It says 'any other object' it does not restrict this to objects allocated
by new[], it does not restrict this to the first object in the areas
returned by new[] but it refers to 'any other object'.
You state that (new int[4])+4 points at an object and therefore
I conclude that (new int[4])+4==new int[0] cannot be true.
My interpretation is that it (new int[4])+4 does not point at an object
(the standard doesn't say it points at an object), and thus
the value of (new int[4])+4==new int[0] should be unspecified
regardless of order of evaluation.
> I believe it
>must also be distinct from any value returned by a previous call to
>malloc() that has not yet been free()'d. However, nothing prohibits it
>from matching any other pointer. Any pointer that does compare equal to
>it can't have been dereferenceable (i.e. it was offset beyond the valid
>range of it's parent object, or it's parent object was deallocated), and
>therefore did not point to an object before the new[] expression was
>evaluated. However, after the evaluation it can point to the newly
>allocated object.
It says 'The pointer returned by the new-expression is non-null and
distinct from the pointer to any other object'
It doesn't say 'The pointer is distinct from the pointer to any
object that existed before the call to new'.
Since it uses 'returned' it seems reasonable to assume that the
statement should at least include the other pointers when the
value actually is returned (and not before new was called).
If new int[0] is evaluated first and we then call new int[4]+4
it seems as though you do not allow them to compare equal because
new int[0] already points at the object.
In practice they can compare equal regardless of order of evaluation.
>> Thus if i4+4==i0 it follows that i4+4 does not point to any object.
>
>If they compare equal, then i4+4 must point at the same object as i0,
>since i0 is unambiguously a pointer to an object.
In that case we can have new int[0]==new int[0], because they could
all point to the same object.
>> >Note that i4+4 neither points at the same object that i4 does, nor does
>> >it point into the same array object than contains the object pointed at
>> >by i4; it's been offset past the end of that array.
>>
>> My interpretation is that it does not point to any object, combine this
>
>You can interpret it that way, and create an implementation that
>supports that interpretation, but the standard doesn't say anything
>about it, one way or the other.
The standard doesn't say that it points to any object.
I interpret this as stating that it does not point to any object.
>> with the suggested correction to the standard (so that pointers to
>> end-plus-one can only be compared to pointers within the same array
>> (of course including the one-plus-end)).
>
>It's a correction only if the current wording is a misstatement of the
>original intent. I don't know of any evidence that it is. Otherwise,
>it's just an ordinary change, not a correction.
There is a footnote somewhere in the standard that makes it explicit
that the end-plus-one can be shared with another object.
(This is of course not normative but it clearly indicates the intent).
This history of changes for == and < also indicate that this was the
intention, (but there were other errors that had to be corrected,
which unfortunately lead to new errors etc.).
It seems as though there are no arguments that convince you, and
since I've better things to do this week (e.g. defending my PhD-thesis)
I see no point in continuing this discussion.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/08 Raw View
Hans Olsson wrote:
....
> It seems as though there are no arguments that convince you, and
> since I've better things to do this week (e.g. defending my PhD-thesis)
> I see no point in continuing this discussion.
I agree. I find your arguments so opaque that I can't even figure out
where our premises differ, much less why we've reached incompatible
conclusions.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/08 Raw View
Steve Clamage wrote:
>
> Barry Margolin <barmar@bbnplanet.com> writes:
[...]
> >Will this work if you allocate the space using malloc()? Malloc() has to
> >return an address suitably aligned for any type of object. This is usually
> >done by returning an address that's a multiple of the LCM of all alignment
> >requirements. So if ints have 4-byte alignment, malloc() must return a
> >multiple of 4, and such a pointer could not be used to point to the above
> >structure.
A convincing argument indeed: There's no address which at the same
time is (4n) and (4n+1).
>
> More generally, the C and C++ standards implicitly assume that
> if sizeof(T1) < sizeof(T2), T1 does not have a stricter alignment
> requirement than T2. Barry's argument shows that using a funny
> alignment like 4*n-1 is unlikely to work.
Really? So if you define struct S { char a[5]; };, and have
sizeof(int)=4, the alignment of S must be at least as strict as
the alignment on int? So if int has 4 byte alignment, S must
have 4 byte alignment as well? (And has to add 3 padding bytes
so that S objects can be put into arrays without holes?)
>
> It is conceivable that an implementation could get away with
> violating those unstated assumptions. But alignment is expected
> to be based on the requirements of the underlying machine, and
> not to be whimsical.
My suggested alignment rule *was* based on the underlying machine.
Especially it was based on the fact that on that machine chars
could be on any address, but ints could be only on addresses which
are multiples of four. The layout was optimized for size under
those restrictions. And without the raw memory allocation
restrictions (aligned for all types), I wouldn't see any problem.
[...]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/04 Raw View
In article <3666D1AC.41C6@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
>
>Hans Olsson wrote:
>>
>> In article <36659C01.2781@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
>> >
>> >Hans Olsson wrote:
>...
>> >> Consider the following:
>> >>
>> >> int*i4=new int[4];
>> >> int*i0=new int[0];
>> >> int*i0a=new int[0];
>>>
>>> AFAIK we might have i4+4==i0, but not i0==i0a.
>...
>> I cannot see i0 as distinct from the pointer to any other object and
>> simultaneously as pointing to the same object as i4+4 (because i4+4==i0,
>> which you argue is allowed because i4+4 and i0 point to the same object).
>
>I'm confused from your wording about whether you are talking about
>distinct pointers, or pointers to distinct objects.
Distinct pointers must in this context mean that the pointers have
distinct values (since new[] returns a value). Loosely this can
be defined as: for all other pointers to objects x we have x!=i0.
I would interpret pointers to distinct objects as examining the
values stored in the object for equality, but this is not possible for i0
(since all the elements in the array are out of bounds).
You seem to believe that 'distinct pointers' mean that the returned
variable is stored at a different address than other pointers.
That's not something that a value-returning function such as new[]
can even attempt to control.
(Don't blame me for the wording; it's from CD2 and unless changed
also in the C++ standard).
Therefore it means that the value of returned by new T[0] is distinct
from the value of any other pointer to an object.
Thus if i4+4==i0 it follows that i4+4 does not point to any object.
> i4 is a distinct
>object from i0. i4 points at an object which is distinct from the one
>that i0 points at. i4+4 is a temporary pointer, which must be distinct
>from both i0 and i4. However, it may point at the same object as i0.
By the same reasoning you allow i0==i0a and i0==i4, as long as
they are stored at different places.
That's unreasonable, contrary to common praxis, and would mean that the
requirement on 'distinct pointers' is meaningless. Furthermore there is
no way to check it since new[] returns a value and not a reference.
(Unless you believe that new[] controls how its return value is stored).
>Note that i4+4 neither points at the same object that i4 does, nor does
>it point into the same array object than contains the object pointed at
>by i4; it's been offset past the end of that array.
My interpretation is that it does not point to any object, combine this
with the suggested correction to the standard (so that pointers to
end-plus-one can only be compared to pointers within the same array
(of course including the one-plus-end)).
This would ensure that the result of i4+4==i0 is unspecified,
and i4+4 does not point to any object.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/04 Raw View
In article <3666667C.3923EB86@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
>Hans Olsson wrote:
>> How could you create a structure/object with less strict alignment
>> than its members?
>
>Well, is there anything in the standard which states that alignment
>must be on integral multiples of a given number?
Alignment must be given as a number of bytes (CD2 3.9):
5 Object types have alignment requirements. 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 require-
ments of its object type.
>What about a compiler which allocates the following struct
>at addresses (4*n-1), if int has alignment 4 (i.e. can be put at
>any 4 byte address)?
The sizeof of the type shall include padding necessary to place
the object in an array, and malloc/operator new/new char[] shall
return memory suitably aligned for any object that fit in the given
size.
There thus must be padding after c and before i in the example:
>struct allows_strange_alignment
>{
> char c;
> int i;
> char d;
>};
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/05 Raw View
Hans Olsson wrote:
>
> In article <3666D1AC.41C6@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
> >
> >Hans Olsson wrote:
> >>
> >> In article <36659C01.2781@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
> >> >
> >> >Hans Olsson wrote:
> >...
> >> >> Consider the following:
> >> >>
> >> >> int*i4=new int[4];
> >> >> int*i0=new int[0];
> >> >> int*i0a=new int[0];
> >>>
> >>> AFAIK we might have i4+4==i0, but not i0==i0a.
> >...
> >> I cannot see i0 as distinct from the pointer to any other object and
> >> simultaneously as pointing to the same object as i4+4 (because i4+4==i0,
> >> which you argue is allowed because i4+4 and i0 point to the same object).
> >
> >I'm confused from your wording about whether you are talking about
> >distinct pointers, or pointers to distinct objects.
>
> Distinct pointers must in this context mean that the pointers have
> distinct values (since new[] returns a value). Loosely this can
> be defined as: for all other pointers to objects x we have x!=i0.
Those aren't distinct pointers; those are distinct pointer values. I
think we're in agreement, however, that new[] must return distinct
pointer values from each call (at least until one of them has ben
released by delete[]).
> I would interpret pointers to distinct objects as examining the
> values stored in the object for equality, but this is not possible for i0
> (since all the elements in the array are out of bounds).
I'm not clear what you mean by this. In what context do you expect this
comparison to occur? What you describe constitutes dereferencing the
pointer, and can't occur when two pointers are only compared for
equality.
> You seem to believe that 'distinct pointers' mean that the returned
> variable is stored at a different address than other pointers.
Sort of; I think you may be misunderstanding what I mean by that. A
pointer is an object. Distinct pointer objects are stored in different
locations. Distinct pointer values can be stored in those distinct
objects. However, those distinct pointer objects can also contain
identical (or at least, equivalent) pointer values.
> That's not something that a value-returning function such as new[]
> can even attempt to control.
I agree with that; if it sounded otherwise, its due to the confusion
we've had about the difference between pointer objects and the pointer
values stored in those objects.
> Therefore it means that the value of returned by new T[0] is distinct
> from the value of any other pointer to an object.
It must be distinct from the value of any other pointer returned by
previous calls to new[], which have not yet been deleted. I believe it
must also be distinct from any value returned by a previous call to
malloc() that has not yet been free()'d. However, nothing prohibits it
from matching any other pointer. Any pointer that does compare equal to
it can't have been dereferenceable (i.e. it was offset beyond the valid
range of it's parent object, or it's parent object was deallocated), and
therefore did not point to an object before the new[] expression was
evaluated. However, after the evaluation it can point to the newly
allocated object.
> Thus if i4+4==i0 it follows that i4+4 does not point to any object.
If they compare equal, then i4+4 must point at the same object as i0,
since i0 is unambiguously a pointer to an object.
> > i4 is a distinct
> >object from i0. i4 points at an object which is distinct from the one
> >that i0 points at. i4+4 is a temporary pointer, which must be distinct
> >from both i0 and i4. However, it may point at the same object as i0.
>
> By the same reasoning you allow i0==i0a and i0==i4, as long as
> they are stored at different places.
No, each of those pointer values was returned by seperate evaluations of
new[], and none of them was delete[]d. Therefore they must each point at
distinct objects. They don't have the same freedom that i4+4 does. The
fact that i4+4 points outside the object allocated at i4, is crucial to
my argument.
Again, I think you're misunderstanding of my argument is due to the
confusion between pointer objects and pointer values. i4 could contain a
value equal to the value of i0, but not at that point in the code. At
that point in the code, i4 must point at different object than i0 points
at. However, i4+4 can point at the same object i0 points at.
> That's unreasonable, contrary to common praxis, and would mean that the
> requirement on 'distinct pointers' is meaningless. Furthermore there is
> no way to check it since new[] returns a value and not a reference.
> (Unless you believe that new[] controls how its return value is stored).
I'll assume that those comments refer to the conclusions that i0==i0a,
and i0==i4, which I didn't make. They don't seem applicable to the
conclusions I did make.
> >Note that i4+4 neither points at the same object that i4 does, nor does
> >it point into the same array object than contains the object pointed at
> >by i4; it's been offset past the end of that array.
>
> My interpretation is that it does not point to any object, combine this
You can interpret it that way, and create an implementation that
supports that interpretation, but the standard doesn't say anything
about it, one way or the other.
> with the suggested correction to the standard (so that pointers to
> end-plus-one can only be compared to pointers within the same array
> (of course including the one-plus-end)).
It's a correction only if the current wording is a misstatement of the
original intent. I don't know of any evidence that it is. Otherwise,
it's just an ordinary change, not a correction.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/03 Raw View
In article <36659C01.2781@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
>
>Hans Olsson wrote:
>>
>> In article <36644292.446B@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
>> Consider the following:
>>
>> int*i4=new int[4];
>> int*i0=new int[0];
>> int*i0a=new int[0];
>>
>> AFAIK we might have i4+4==i0, but not i0==i0a.
>>
>> How do you explain it?
>
>I think [0] is prohibited.
Not in new[]-expressions. In CD2 5.3.4:
8 When the value of the expression in a direct-new-declarator is zero,
the allocation function is called to allocate an array with no ele-
ments. The pointer returned by the new-expression is non-null and
distinct from the pointer to any other object.
I cannot see i0 as distinct from the pointer to any other object and
simultaneously as pointing to the same object as i4+4 (because i4+4==i0,
which you argue is allowed because i4+4 and i0 point to the same object).
>> Could it be null?
>
>If you decrement it, the result must point to the last element of the
>array, so you'd have to have distiguishable null pointers, a seperate
>one for each array.
I was more thinking of only one array (=last one in memory) having
one_past_end as the null-pointer.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/03 Raw View
In article <3665EEE2.5C6F67EA@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
>AllanW@my-dejanews.com wrote:
>....
>> In that case, the answer to your question (to the advantages of
>> changing the standard) is:
>> The wording used in that sentence makes some people think that it
>> means something different, and in fact quite unreasonable. The
>> people who share this interpretation are left with three choices:
>> 1. Expect that compilers will behave in this unreasonable way.
>> 2. Disregard their own interpretation of this sentence.
>> 3. Ask that the sentence be reworded so that we all give it the
>> same reasonable meaning.
>> The general concensus is that option 3 is the best.
>
>I wouldn't oppose clarified wording, though I'm not sure how it should
>be rewritten. I'd like to retain the current meaning, however. I don't
>see any benefit in making some comparisons of pointers for equality
>undefined behavior, as Hans originally suggested.
I couldn't find any such statement by me. I have twice suggested
implementation-defined, undefined, etc. (in various orders).
I've later amended this to 'unspecified'.
>example:
>
> int i;
> int *silly(const int *p)
> {
> if(p==&i)
> i++;
> return &i;
> }
>
>I can't figure out what such a function would be useful for, but I don't
>think it should trigger undefined behavior, regardless of what value is
>passed to it.
The result of 'p==&i' is currently unspecified unless
p is null, points to an object or to end-plus-one of an array.
The change would be to also make the result of comparison with end-plus-one
for other arrays ('i' is seen as an array of length 1) unspecified.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/03 Raw View
Hans Olsson wrote:
>
> In article <365B6778.9D62B8E8@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
> >
> >Hans Olsson wrote:
> [...]
> >I was thinking more in terms of
> >
> > void *start_area;
> > ptrdiff_t offset;
> >
> >After all, the start_area for an object might not be suitably aligned
> >for a T*; it could be the start of a structure or union containing a T.
> >The after_area would be needed only for bounds checking, which was not
> >what I was talking about.
>
> How could you create a structure/object with less strict alignment
> than its members?
Well, is there anything in the standard which states that alignment
must be on integral multiples of a given number?
What about a compiler which allocates the following struct
at addresses (4*n-1), if int has alignment 4 (i.e. can be put at
any 4 byte address)?
struct allows_strange_alignment
{
char c;
int i;
char d;
};
With traditional alignment, this struct must be layed out like this:
c___iiiid___
With this strange alignment rule, the object could be layed out
like this:
ciiiid__
Now, in memory an array of 3 allows_strange_alignment objects would
look like this (the numbers in the first line are (address % 4))
0123012301230123012301230123
ciiiid__ciiiid__ciiiid__
As you see, the int is always aligned correctly, and the size of
allows_strange_alignment has been reduced to 8 without changing
the order of elements (which would not be allowed here).
I doubt that any real compiler does this, and I don't know if the
win would justify the additional complexity (or if it would really
be a win generally - it may generate extra space between objects
of different type, since their alignments may not fit despite having
the same alignment size). However, I think this would be legal.
[...]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/12/03 Raw View
In article <73u28f$rld$1@news.lth.se>,
Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
> However, it would be nice if the standard had said that
> the result of comparing one-past-end of one array and pointers that
> things in other arrays gives an {implementation,un,..}-defined result.
In article <3665EEE2.5C6F67EA@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
> I wouldn't oppose clarified wording, though I'm not sure how it should
> be rewritten. I'd like to retain the current meaning, however. I don't
> see any benefit in making some comparisons of pointers for equality
> undefined behavior, as Hans originally suggested.
I don't think anyone really wants to make the behavior undefined.
Hans suggested an "(implementation,un,...)-defined result." I
think his intent was to avoid the distinction between
implementation-defined, undefined, unspecified, etc.
The code should be considered well-formed and the behavior should
be defined, but the result should be unspecified. I hope that I'm
speaking for everyone here; does anyone disagree with that?
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/03 Raw View
Hans Olsson wrote:
>
> In article <36659C01.2781@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
> >
> >Hans Olsson wrote:
...
> >> Consider the following:
> >>
> >> int*i4=new int[4];
> >> int*i0=new int[0];
> >> int*i0a=new int[0];
>>
>> AFAIK we might have i4+4==i0, but not i0==i0a.
...
> I cannot see i0 as distinct from the pointer to any other object and
> simultaneously as pointing to the same object as i4+4 (because i4+4==i0,
> which you argue is allowed because i4+4 and i0 point to the same object).
I'm confused from your wording about whether you are talking about
distinct pointers, or pointers to distinct objects. i4 is a distinct
object from i0. i4 points at an object which is distinct from the one
that i0 points at. i4+4 is a temporary pointer, which must be distinct
from both i0 and i4. However, it may point at the same object as i0.
Note that i4+4 neither points at the same object that i4 does, nor does
it point into the same array object than contains the object pointed at
by i4; it's been offset past the end of that array.
> >> Could it be null?
> >
> >If you decrement it, the result must point to the last element of the
> >array, so you'd have to have distiguishable null pointers, a seperate
> >one for each array.
>
> I was more thinking of only one array (=last one in memory) having
> one_past_end as the null-pointer.
There's may be some reason why that wouldn't work, but I can't think of
any off hand.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/03 Raw View
Hans Olsson wrote:
>
> In article <3665EEE2.5C6F67EA@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
...
> >be rewritten. I'd like to retain the current meaning, however. I don't
> >see any benefit in making some comparisons of pointers for equality
> >undefined behavior, as Hans originally suggested.
>
> I couldn't find any such statement by me. I have twice suggested
> implementation-defined, undefined, etc. (in various orders).
OK, I realize now that you meant that the value was undefined, not the
behavior. That's better, but still not ideal.
> >example:
> >
> > int i;
> > int *silly(const int *p)
> > {
> > if(p==&i)
> > i++;
> > return &i;
> > }
> >
> >I can't figure out what such a function would be useful for, but I don't
> >think it should trigger undefined behavior, regardless of what value is
> >passed to it.
Correct that to:
I wouldn't expect p==&i to be true for any value of 'p' except one that
actually points at 'i'.
> The result of 'p==&i' is currently unspecified unless
> p is null, points to an object or to end-plus-one of an array.
The value of p==&i is defined to return true if certain conditions are
true, and false if none of them apply; it is never unspecified.
> The change would be to also make the result of comparison with end-plus-one
> for other arrays ('i' is seen as an array of length 1) unspecified.
I'm confused by that statement. Consider:
int a[3];
I thought from your previous statements that you wanted the expression
a+3==&i to have an undefined value. Therefore, silly(a+3) might or might
not increment i, which I consider to be innappropriate. Do you think
that's appropriate?
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Barry Margolin <barmar@bbnplanet.com>
Date: 1998/12/03 Raw View
In article <3666667C.3923EB86@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>Well, is there anything in the standard which states that alignment
>must be on integral multiples of a given number?
>
>What about a compiler which allocates the following struct
>at addresses (4*n-1), if int has alignment 4 (i.e. can be put at
>any 4 byte address)?
>
>struct allows_strange_alignment
>{
> char c;
> int i;
> char d;
>};
>
>With traditional alignment, this struct must be layed out like this:
>
>c___iiiid___
>
>With this strange alignment rule, the object could be layed out
>like this:
>
>ciiiid__
Will this work if you allocate the space using malloc()? Malloc() has to
return an address suitably aligned for any type of object. This is usually
done by returning an address that's a multiple of the LCM of all alignment
requirements. So if ints have 4-byte alignment, malloc() must return a
multiple of 4, and such a pointer could not be used to point to the above
structure.
--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/03 Raw View
Barry Margolin <barmar@bbnplanet.com> writes:
>In article <3666667C.3923EB86@physik.tu-muenchen.de>,
>Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>>Well, is there anything in the standard which states that alignment
>>must be on integral multiples of a given number?
>>What about a compiler which allocates the following struct
>>at addresses (4*n-1), if int has alignment 4 (i.e. can be put at
>>any 4 byte address)?
>>struct allows_strange_alignment
>>{
>> char c;
>> int i;
>> char d;
>>};
>>With traditional alignment, this struct must be layed out like this:
>>c___iiiid___
>>With this strange alignment rule, the object could be layed out
>>like this:
>>ciiiid__
>Will this work if you allocate the space using malloc()? Malloc() has to
>return an address suitably aligned for any type of object. This is usually
>done by returning an address that's a multiple of the LCM of all alignment
>requirements. So if ints have 4-byte alignment, malloc() must return a
>multiple of 4, and such a pointer could not be used to point to the above
>structure.
More generally, the C and C++ standards implicitly assume that
if sizeof(T1) < sizeof(T2), T1 does not have a stricter alignment
requirement than T2. Barry's argument shows that using a funny
alignment like 4*n-1 is unlikely to work.
It is conceivable that an implementation could get away with
violating those unstated assumptions. But alignment is expected
to be based on the requirements of the underlying machine, and
not to be whimsical.
Machine requirements tend to be pretty straightforward. Typically,
aligment is no stricter than the size of the object, and smaller
objects do not have stricter requirements than larger objects.
A compiler might choose to use stricter alignments than are
actually required by the machine for performance reasons, but
again, whimsical choices are likely to cause problems.
--
Steve Clamage, stephen.clamage@sun.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/12/04 Raw View
In article <3666D9EF.167E@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
> Hans Olsson wrote:
> >
> > In article <3665EEE2.5C6F67EA@wizard.net>,
> > James Kuyper <kuyper@wizard.net> wrote:
> > > int i;
> > > int *silly(const int *p)
> > > {
> > > if(p==&i)
> > > i++;
> > > return &i;
> > > }
> > The change would be to also make the result of comparison with end-plus-one
> > for other arrays ('i' is seen as an array of length 1) unspecified.
>
> I'm confused by that statement. Consider:
>
> int a[3];
>
> I thought from your previous statements that you wanted the expression
> a+3==&i to have an undefined value. Therefore, silly(a+3) might or might
> not increment i, which I consider to be innappropriate. Do you think
> that's appropriate?
I think that it is appropriate under either of the two definitions.
Under the interpretation you've been touting, it's possible but not
required that i follows a[] in memory. Therefore a+3 might or might
not point to i, and silly might or might not increment i.
By the suggested rewording of the statement, the results of comparing
a+3 to &i has an unspecified value. Once again, then, silly might or
might not increment i.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/04 Raw View
Steve Clamage wrote:
>
> Barry Margolin <barmar@bbnplanet.com> writes:
>
> >In article <3666667C.3923EB86@physik.tu-muenchen.de>,
> >Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> >>Well, is there anything in the standard which states that alignment
> >>must be on integral multiples of a given number?
>
> >>What about a compiler which allocates the following struct
> >>at addresses (4*n-1), if int has alignment 4 (i.e. can be put at
> >>any 4 byte address)?
>
> >>struct allows_strange_alignment
> >>{
> >> char c;
> >> int i;
> >> char d;
> >>};
...
I couldn't find a definition of alignment within the C++ standard.
However, it incorporates the C89 standard by reference. I don't have a
copy of the C89 standard, but the draft C9X standard defines alignment
as the "requirement that objects of a particular type be located on
storage boundaries with addresses that are particular multiples of a
byte address". This strangely aligned struct violates that description.
> More generally, the C and C++ standards implicitly assume that
> if sizeof(T1) < sizeof(T2), T1 does not have a stricter alignment
I don't think so. Could you identify some locations where that
assumption is used.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: comeau@panix.com (Greg Comeau)
Date: 1998/12/04 Raw View
In article <36659C01.2781@wizard.net> James Kuyper <kuyper@wizard.net> writes:
>Hans Olsson wrote:
>> int*i0=new int[0];
>I think [0] is prohibited.
new T[0] is fine and results in a unique pointer.
The mentality is that it gives a sole well-formed predicatable behavior
unlike some malloc()s, and also can work with new T[x] where x might be zero
sometimes simplifying some code.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C/C++ 4.2.38 -- New Release! We now do Windows too.
Email: comeau@comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
*** WEB: http://www.comeaucomputing.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/04 Raw View
James Kuyper <kuyper@wizard.net> writes:
>I couldn't find a definition of alignment within the C++ standard.
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/02 Raw View
AllanW@my-dejanews.com wrote:
>
> In article <36634863.71696018@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
> >
> > Hans Olsson wrote:
> > ....
> > > However, it would be nice if the standard had said that
> > > the result of comparing one-past-end of one array and pointers that
> > > things in other arrays gives an {implementation,un,..}-defined result.
> >
> > What are the advantages of such a change? It's hard to think of a good
> > example where it would be legitimate to compare two such pointers for
> > equality, but I don't see any reason for making it a potentially lethal
> > mistake to do so.
>
> My answer to your question would depend on your interpretation of this
> paragraph from the standard, which can be seen as contradictary. Bear
> with me; I didn't have time to re-write my ideas concisely. Besides,
> I've seen each of these points of view espoused elsewhere. Maybe it's
> time to collect them all together, because when we lay them side-by-side
> we may be able to understand each other.
...
> pointer conversions) can be compared for equality. Two pointers of
> the same type type compare equal if and only if they are both null,
> both point to the same object or function, or both point one past
> the end of the same array.
...
> But what happens when a points one past the end of some array, and b
> points at the beginning of some OTHER array? If b's array happens to
> be immediately after a's array in memory, the addresses might be the
> same. In this case, the last item in [5.9] p2 allows the compiler to
> give a<=b and a>=b any values it likes. Most implementations would
> yield true in this case.
>
> But the last sentance of [5.10] p1 uses the phrase "if and only if,"
> which seems to means that the pointer must return true in the cases
> listed -- and false in all other cases! Since the sentance doesn't
> mention the case where a is past-the-end of one array and b is at
> the beginning of the next array, this sentance seems to mean that
> the comparison must not yield the value true.
However it does mention the case where 'a' points one past the end of
the array, and 'b' points one past the end of the array. It also
mentions the case where 'a' points at the beginning of an array, and 'b'
points at the beginning of an array. It nowhere states that those two
cases are exclusive. It doesn't prohibit 'a' from being, simultaneously,
a pointer one past the end of an array, and a pointer to the start of
another object.
It says "A is true iff (B OR C OR D is true)". You can't derive from
that the conclusion that conditions C and D are mutually exclusive.
You'll find repetitions of this same explanation about three different
times, a few dozen messages prior to this one on the same thread (I
think - it may have been a different thread). I'm getting pretty tired
of going over the same material time and time again.
> In my opinion, there are (at least?) three reasonable interpretations
> of these words.
>
> 1. The last sentance is very important. A pointer to past-the-end of
I'll agree that it's very important. I disagree with every conclusion
you draw from that sentence in this paragraph:
> one array must never compare equal to a pointer to the beginning
> of another array (with certain exceptions already noted, such as
> within the same struct). The system must provide at least one
> byte of padding between such objects, or else must expand the
> concept of a pointer to include the pointer's "starting place."
...
> 2. The last sentance doesn't matter. We understand (from [5.9] or from
I disagree with this.
...
> 3. The standard is self-contradictary. The first sentance in [5.10]p1
I disagree with this.
...
> 4. Something else.
>
> If you feel that none of the above interpretations is close to your
> point of view, then please state it here. Do you at least agree that
> the standard seems to contradict itself? Surely there can be no
> objection to changing words that contradict themselves... can there?
I feel that the existing words are not self contradictory, nor do they
contradict common practice. They do not require padding between objects.
They do not prohibit the same pointer from being both a pointer to one
object, and simultaneously a pointer one past the end of a preceeding
array. Such a pointer should, according to the words of that section,
compare equal to any other pointer with that same property, with respect
to the same object and same array, because they simultaneously meet both
the second and the third criteria for comparing equal.
I think the disagreement comes from the idea that pointing at an object
is a property only of pointers derived from expressions involving that
object. The standard contains no such definition. The most practical
definition of "points at" would be in terms of the results when the
pointer is de-referenced. Since de-referencing a pointer one past the
end of an array allows undefined behavior, "points at" is necessarily
implementation-specific for such pointers.
On most implementations I've seen, a pointer one past the end of an
array, if successfully dereferenced, will usually retrieve/change the
value stored at the start of another object; therefore it should compare
equal to a (suitably cast) pointer to that other object. Oddly enough,
that's exactly what most implementations I've used do :-)
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/02 Raw View
In article <36644292.446B@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
>
>Hans Olsson wrote:
>...
>> The standard says that the two pointer compare equal iff:
>> * they both are null
>> * they both point to the same object
>> * they both are end-plus-one of the same array
>>
>> The question is thus if the end-plus-one of one array can _point_ to
>> an unrelated object. Claiming that it can because the addresses compare
>> equal is circular logic.
>
>It's not circular logic. It's a choice among unspecified behaviors.
>The standard says nothing about whether or not a pointer to end_plus_one
>of one array can also be a pointer to the beginning of another object.
>Therefore, it's legal for an implementation to allow such to be true. If
>an implementation does allow that, then equality tests of such pointers
>should come up equal.
So you are saying that the end-plus-one of an array might _point_ to a
different object.
Consider the following:
int*i4=new int[4];
int*i0=new int[0];
int*i0a=new int[0];
AFAIK we might have i4+4==i0, but not i0==i0a.
How do you explain it?
The arrays are not the same and thus they do not point to end-plus-one
of the same array, and they can't point to the same object
(i0 is guaranteed to be distinct from the pointer to any other object).
>Note that the implementation is not free to make arbitrary pointers
>point to the same thing. What makes this special case possible is that
>the one_past_the_end pointer doesn't have to point at anything; a
>strictly conforming program can't dereference. Therefore, an
>implmentation is free to make it point at anything it wants, outside the
>array.
Could it be null?
>It's a historical fact that many compilers have used memory address
>values as pointers, allocated unrelated objects next to each other with
>no padding (if alignment issues allowed it), implemented no boundary
>checking on pointers, and implemented comparisons between pointers by
>simply comparing their address values. A large fraction of all the C
>code ever written was on systems with such characteristics. I see no
>evidence that the committee intended the wording to be interpreted in
>such a way as to prohibit such implementations.
It's clear from e.g. footnotes in the standard that the intention is
to allow this, but I believe that the actual wording either says
something differently or at least is unclear.
Furthermore I would say that I see no evidence that the committee intended
to allow any other implementation.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/02 Raw View
Hans Olsson wrote:
>
> In article <36644292.446B@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
> >
> >Hans Olsson wrote:
> >...
> >> The standard says that the two pointer compare equal iff:
> >> * they both are null
> >> * they both point to the same object
> >> * they both are end-plus-one of the same array
> >>
> >> The question is thus if the end-plus-one of one array can _point_ to
> >> an unrelated object. Claiming that it can because the addresses compare
> >> equal is circular logic.
> >
> >It's not circular logic. It's a choice among unspecified behaviors.
> >The standard says nothing about whether or not a pointer to end_plus_one
> >of one array can also be a pointer to the beginning of another object.
> >Therefore, it's legal for an implementation to allow such to be true. If
> >an implementation does allow that, then equality tests of such pointers
> >should come up equal.
>
> So you are saying that the end-plus-one of an array might _point_ to a
> different object.
That's already been said a few dozen times in this thread, and that's
what I just said in the previous paragraph, but I suppose I can bring
myself to repeat it one more time. Yes, a pointer to one past the end of
an array might point to a different object as well.
> Consider the following:
>
> int*i4=new int[4];
> int*i0=new int[0];
> int*i0a=new int[0];
>
> AFAIK we might have i4+4==i0, but not i0==i0a.
>
> How do you explain it?
I think [0] is prohibited. However, even it it's allowed, i0 and i0a are
special cases; they are simultaneously pointers to the beginning of the
array, and pointers one past its end; As pointers to the beginning of
the array, they must be distiguishable from each other, and from
pointers to the beginning of any other array. Padding between objects is
not required, but every object is required to take up at least one byte,
whether or not it uses that byte for anything.
> >Note that the implementation is not free to make arbitrary pointers
> >point to the same thing. What makes this special case possible is that
> >the one_past_the_end pointer doesn't have to point at anything; a
> >strictly conforming program can't dereference. Therefore, an
> >implmentation is free to make it point at anything it wants, outside the
> >array.
>
> Could it be null?
If you decrement it, the result must point to the last element of the
array, so you'd have to have distiguishable null pointers, a seperate
one for each array. I can't think of any good reason for doing that,
except as an excersize in standards-twisting. There may be other good
reasons why it won't work; that's just the first one I thought of.
> >It's a historical fact that many compilers have used memory address
> >values as pointers, allocated unrelated objects next to each other with
> >no padding (if alignment issues allowed it), implemented no boundary
> >checking on pointers, and implemented comparisons between pointers by
> >simply comparing their address values. A large fraction of all the C
> >code ever written was on systems with such characteristics. I see no
> >evidence that the committee intended the wording to be interpreted in
> >such a way as to prohibit such implementations.
>
> It's clear from e.g. footnotes in the standard that the intention is
> to allow this, but I believe that the actual wording either says
> something differently or at least is unclear.
Many people consider it unclear, so by definition it IS unclear;
however, I don't think it's faulty.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/12/02 Raw View
> > > Hans Olsson wrote:
> > > ....
> > > > However, it would be nice if the standard had said that
> > > > the result of comparing one-past-end of one array and pointers that
> > > > things in other arrays gives an {implementation,un,..}-defined result.
> > In article <36634863.71696018@wizard.net>,
> > James Kuyper <kuyper@wizard.net> wrote:
> > > What are the advantages of such a change?
> AllanW@my-dejanews.com wrote:
> > My answer to your question would depend on your interpretation of this
> > paragraph from the standard, which can be seen as contradictary.
> ...
> > But the last sentance of [5.10] p1 uses the phrase "if and only if,"
> > which seems to means that the pointer must return true in the cases
> > listed -- and false in all other cases!
...
> > In my opinion, there are (at least?) three reasonable interpretations
> > of these words.
> >
> > 1. The last sentance is very important. A pointer to past-the-end of
In article <3664849C.15FB@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
> I'll agree that it's very important. I disagree with every conclusion
> you draw from that sentence in this paragraph:
In that case, the answer to your question (to the advantages of
changing the standard) is:
The wording used in that sentence makes some people think that it
means something different, and in fact quite unreasonable. The
people who share this interpretation are left with three choices:
1. Expect that compilers will behave in this unreasonable way.
2. Disregard their own interpretation of this sentence.
3. Ask that the sentence be reworded so that we all give it the
same reasonable meaning.
The general concensus is that option 3 is the best.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/03 Raw View
AllanW@my-dejanews.com wrote:
....
> In that case, the answer to your question (to the advantages of
> changing the standard) is:
> The wording used in that sentence makes some people think that it
> means something different, and in fact quite unreasonable. The
> people who share this interpretation are left with three choices:
> 1. Expect that compilers will behave in this unreasonable way.
> 2. Disregard their own interpretation of this sentence.
> 3. Ask that the sentence be reworded so that we all give it the
> same reasonable meaning.
> The general concensus is that option 3 is the best.
I wouldn't oppose clarified wording, though I'm not sure how it should
be rewritten. I'd like to retain the current meaning, however. I don't
see any benefit in making some comparisons of pointers for equality
undefined behavior, as Hans originally suggested.
example:
int i;
int *silly(const int *p)
{
if(p==&i)
i++;
return &i;
}
I can't figure out what such a function would be useful for, but I don't
think it should trigger undefined behavior, regardless of what value is
passed to 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/12/01 Raw View
In article <36634863.71696018@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
> Hans Olsson wrote:
> ....
> > However, it would be nice if the standard had said that
> > the result of comparing one-past-end of one array and pointers that
> > things in other arrays gives an {implementation,un,..}-defined result.
>
> What are the advantages of such a change? It's hard to think of a good
> example where it would be legitimate to compare two such pointers for
> equality, but I don't see any reason for making it a potentially lethal
> mistake to do so.
My answer to your question would depend on your interpretation of this
paragraph from the standard, which can be seen as contradictary. Bear
with me; I didn't have time to re-write my ideas concisely. Besides,
I've seen each of these points of view espoused elsewhere. Maybe it's
time to collect them all together, because when we lay them side-by-side
we may be able to understand each other.
5.10 Equality operators [expr.eq]
1 The == (equal to) and the != (not equal to) operators have the same
semantic restrictions, conversions, and result type as the relational
operators except for their lower precedence and truth-value result.
[ Note: a<b == c<d is true whenever a<b and c<d have the same truth
value. ] Pointers to objects or functions of the same type (after
pointer conversions) can be compared for equality. Two pointers of
the same type type compare equal if and only if they are both null,
both point to the same object or function, or both point one past
the end of the same array.
The first sentance states that the semantics are the same "except for
their ... truth-value result." One might assume, then, that if a<=b
and a>=b are both true, then a==b must also be true.
But what happens when a points one past the end of some array, and b
points at the beginning of some OTHER array? If b's array happens to
be immediately after a's array in memory, the addresses might be the
same. In this case, the last item in [5.9] p2 allows the compiler to
give a<=b and a>=b any values it likes. Most implementations would
yield true in this case.
But the last sentance of [5.10] p1 uses the phrase "if and only if,"
which seems to means that the pointer must return true in the cases
listed -- and false in all other cases! Since the sentance doesn't
mention the case where a is past-the-end of one array and b is at
the beginning of the next array, this sentance seems to mean that
the comparison must not yield the value true.
In my opinion, there are (at least?) three reasonable interpretations
of these words.
1. The last sentance is very important. A pointer to past-the-end of
one array must never compare equal to a pointer to the beginning
of another array (with certain exceptions already noted, such as
within the same struct). The system must provide at least one
byte of padding between such objects, or else must expand the
concept of a pointer to include the pointer's "starting place."
If this is your interpretation, then the value in Hans Olsson's
suggestion is to relax the rule. Requiring compilers to perform
the comparisons in this way would incur a cost, in terms of all
programs being fatter and slower. The payback for this cost would
be minimal: it allows guaranteed, predictable results in
situations that are unlikely to arise in good programs. There are
no existing compilers that work this way, so it didn't come from
standard practice. In short, this is a bad language feature, and
we want to remove it.
2. The last sentance doesn't matter. We understand (from [5.9] or from
experience) that programmers must not expect any particular result
when they compare two pointers, one of which points to past-the-end
of some array and the other of which points to the beginning of some
other array. Therefore, the compiler is free to yield true OR false,
as it sees fit, and we don't have to go to any great lengths here.
If this is your interpretation, then the value in Hans Olsson's
suggestion is the same as the value of the whole standard: to make sure
that we agree with each other, that everything is well understood.
The last sentance, which seems to contradict the rest, should be
removed or re-worded so that we don't think it contradicts your
interpretation.
3. The standard is self-contradictary. The first sentance in [5.10]p1
says that the semantics of operator== are compatible with the
semantics of the relational operators. But the last sentance
contradicts this by stating explicit cases where pointers should
compare equal, in a way that doesn't match the relational operators.
A thing cannot be both different and the same at the same time.
If this is your interpretation, then the value in Hans Olsson's
suggestion is to remove the contradiction, explicitly stating
what we all seem to feel the standard meant to say but didn't say.
4. Something else.
If you feel that none of the above interpretations is close to your
point of view, then please state it here. Do you at least agree that
the standard seems to contradict itself? Surely there can be no
objection to changing words that contradict themselves... can there?
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/01 Raw View
Hans Olsson wrote:
...
> The standard says that the two pointer compare equal iff:
> * they both are null
> * they both point to the same object
> * they both are end-plus-one of the same array
>
> The question is thus if the end-plus-one of one array can _point_ to
> an unrelated object. Claiming that it can because the addresses compare
> equal is circular logic.
It's not circular logic. It's a choice among unspecified behaviors.
The standard says nothing about whether or not a pointer to end_plus_one
of one array can also be a pointer to the beginning of another object.
Therefore, it's legal for an implementation to allow such to be true. If
an implementation does allow that, then equality tests of such pointers
should come up equal.
Note that the implementation is not free to make arbitrary pointers
point to the same thing. What makes this special case possible is that
the one_past_the_end pointer doesn't have to point at anything; a
strictly conforming program can't dereference. Therefore, an
implmentation is free to make it point at anything it wants, outside the
array.
It's a historical fact that many compilers have used memory address
values as pointers, allocated unrelated objects next to each other with
no padding (if alignment issues allowed it), implemented no boundary
checking on pointers, and implemented comparisons between pointers by
simply comparing their address values. A large fraction of all the C
code ever written was on systems with such characteristics. I see no
evidence that the committee intended the wording to be interpreted in
such a way as to prohibit such implementations.
Furthermore, I see no value in such a prohibition. It would require
either wasteful padding or fat pointers. Can you give an example of any
benefit from such a prohibition that would offset those disadvantages?
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/12/01 Raw View
James Kuyper <kuyper@wizard.net> wrote:
> The problem that I was trying to solve was the claim that the
> standard requires pointers derived from different objects to compare
> unequal. I dispute that claim.
Hans Olsson wrote:
> The standard says that the two pointer compare equal iff:
> * they both are null
> * they both point to the same object
> * they both are end-plus-one of the same array
>
> The question is thus if the end-plus-one of one array can _point_
> to an unrelated object. Claiming that it can because the addresses
> compare equal is circular logic.
Here's example code to add more fodder to the argument:
// Assume that sizeof(int) = 2*sizeof(short)
int i[10];
short s[20];
int * ip = &i[10];
short * sp = &s[0];
Pointer 'ip' points to one-past-the-end of array 'i', while pointer
'sp' points to the first member if array 's'. Assuming that 'i' and
's' are allocated in memory in the same order as their declarations
and that there is no padding between them, and assuming a linear
(not segmented) memory architecture, and that the address of an
object is the address of its first byte, then the value of 'ip'
will be the same as 'sp'.
Clearly, 'ip' and 'sp' both point to the "same object". Or at
least they point to the same byte. And they point to the same byte
that is one-past-the-end of the same array. How does this affect
the interpretation of the 2nd rule (above) for equality?
James Kuyper <kuyper@wizard.net> wrote:
> It was said that this interpretation requires padding between
> objects. I was only trying to show it was implementable without
> such padding. Since these two arrays [which are members of the
> same struct] are different parts of the same object, that claim
> doesn't apply.
I agree with James's interpretation. To answer my own question
above, my example doesn't change the interpretation of the 2nd
rule at all. No padding is required, but padding is certainly
allowed.
More to the point, while 'ip' and 'sp' may have the same value,
the standard makes no guarantee that they are the same, nor does
it guarantee that they are different. Which makes rules 2 and 3
irrelevant to this situation.
Hans Olsson wrote:
> It does at least require extra memory, either in the pointers or
> as padding.
I don't buy that interpretation. And it's obvious that supporting
such a claim would force many working implementations to be branded
nonconforming.
-- David R. Tribble, dtribble@technologist.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/01 Raw View
Hans Olsson wrote:
....
> However, it would be nice if the standard had said that
> the result of comparing one-past-end of one array and pointers that
> things in other arrays gives an {implementation,un,..}-defined result.
What are the advantages of such a change? It's hard to think of a good
example where it would be legitimate to compare two such pointers for
equality, but I don't see any reason for making it a potentially lethal
mistake to do so.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/01 Raw View
In article <36630176.83E96047@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
>Hans Olsson wrote:
>>
>>
>> We thus have a complex solution that does not completely solve
>> the problem it was introduced to solve (i.e. pointers to end-plus-one
>> of one array might compare equal to another array).
>
>I don't consider that a problem, and your further comments suggest that
>you agree.
I don't consider that a problem, but a slight defect in the standard.
>The problem that I was trying to solve was the claim that the
>standard requires pointers derived from different objects to compare
>unequal. I dispute that claim.
The standard says that the two pointer compare equal iff:
* they both are null
* they both point to the same object
* they both are end-plus-one of the same array
The question is thus if the end-plus-one of one array can _point_ to
an unrelated object. Claiming that it can because the addresses compare
equal is circular logic.
>It was said that this interpretation
>requires padding between objects. I was only trying to show it was
>implementable without such padding. Since these two arrays are different
>parts of the same object, that claim doesn't apply.
It does at least require extra memory, either in the pointers or
as padding.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/12/01 Raw View
In article <36634863.71696018@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
>Hans Olsson wrote:
>....
>> However, it would be nice if the standard had said that
>> the result of comparing one-past-end of one array and pointers that
>> things in other arrays gives an {implementation,un,..}-defined result.
>
>What are the advantages of such a change?
To warn programmers that the comparison is not a good thing,
be compatible with the C-standard, document how compilers normally do it,
look similar to the definition of '<','>','<=','>=', and
correspond to the likely intention of the standard committee.
What are the disadvantages of such a change?
>It's hard to think of a good
>example where it would be legitimate to compare two such pointers for
>equality, but I don't see any reason for making it a potentially lethal
>mistake to do so.
I don't care much about the exact wording. Making it undefined might be to
overdo it, whereas implementation-defined might be too hard on implementors.
The right wording should correspond to the result of comparing those
pointers with '<', where I believe it is _unspecified_ whether the
result is true or false. (Or is the result merely 'unspecified'?)
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/30 Raw View
In article <365ED8B0.E6396114@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
>Hans Olsson wrote:
>> That was not clear to me, and in a different thread someone mentioned
>> a compiler that from 'void f(int (&x)[1],int i) { x[i];}'
>> could conclude that i=0. This seems to contradict your assertion,
>> and I would like to know how the standard handles this situation.
>
>It says that the '1' in that declaration is irrelevant; it that context
>[1] is equivalent to [].
Neither CD2 nor my compilers agree with you. The reason is that x
is a reference to an array of length 1 and not an array of length 1
(which would decay into a pointer).
>> And how about:
>>
>> union U {
>> int arr1[1];
>> int arr2[2][1];
>> int arr9[9];
>> } u;
>>
>> What are start_area and after_area for arr2[0] and arr2[1]?
>
>It's permissible to set them both to &u and &u+1.
We thus have a complex solution that does not completely solve
the problem it was introduced to solve (i.e. pointers to end-plus-one
of one array might compare equal to another array).
It might solve the problem (if it is a problem) in some cases, but I'm not
sure exactly when.
BTW: What other values are 'permissible'?
>> Or what if the union has its own 'operator new' that returns elements
>> from one static array of unions?
>> We now suddenly have another array to consider, which might or might
>> now change start_area and after_area.
>
>The contents of the pointer are manipulated by the imlementation, not by
>your operator new. The implementation would set start_area to point to
>the start of the largest enclosing object, and end_area to point one
>past the end of it. The net result could be that pointers could compare
>equal, if one points to the beginning of one object, and the other
>points one-past-the-end of a seperately allocated object.
I interpret this as saying that 'new' takes the result of 'operator new'
and sets 'start_area' and 'end_area' to limits of the allocated
object.
Apart from the fact that I don't know where you have got this idea
from it also causes two other problems:
* POD-objects can be allocated directly from global 'operator new'.
Where are the limits of the object in that case?
* The class-specific 'operator new' will operate with pointers pointing
to the same point as created by 'new'.
These pointer must compare equal and behave in the same way
(the latter follows because pointers are iterators), which
seems to contradict what you said.
>> They have supported the comparisons, but the results are not always
>> well-defined, i.e. the pointer to one array and one-past-end of another
>> might or might not compare equal depending on how the arrays are
>> allocated.
>
>The result of an equality comparison is very well defined: to paraphrase
>it, the pointers compare equal if and only if they point to the same
>thing. All null pointers are treated as pointing at the same non-thing.
>All pointers pointing one past the end of an array are treated as
>pointing at the same thing, which might not actually exist.
>
>Whether or not the pointers point at the same thing depends upon the
>implementation, but that's a different issue. Whether two things are the
>same is not something an implementation can decide arbitrarily: if they
>are both derefencable, you must always get the same result from
>dereferencing either pointer. Therefore, the only freedom of
>interpretation the implementation has is with regard to pointers that
>aren't dereferencable, such as pointers to one past the end of an array.
I don't see how this differs from my statement.
However, it would be nice if the standard had said that
the result of comparing one-past-end of one array and pointers that
things in other arrays gives an {implementation,un,..}-defined result.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/30 Raw View
Hans Olsson wrote:
>
> In article <365ED8B0.E6396114@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
....
> >> And how about:
> >>
> >> union U {
> >> int arr1[1];
> >> int arr2[2][1];
> >> int arr9[9];
> >> } u;
> >>
> >> What are start_area and after_area for arr2[0] and arr2[1]?
> >
> >It's permissible to set them both to &u and &u+1.
>
> We thus have a complex solution that does not completely solve
> the problem it was introduced to solve (i.e. pointers to end-plus-one
> of one array might compare equal to another array).
I don't consider that a problem, and your further comments suggest that
you agree. The problem that I was trying to solve was the claim that the
standard requires pointers derived from different objects to compare
unequal. I dispute that claim. It was said that this interpretation
requires padding between objects. I was only trying to show it was
implementable without such padding. Since these two arrays are different
parts of the same object, that claim doesn't apply.
> It might solve the problem (if it is a problem) in some cases, but I'm not
> sure exactly when.
>
> BTW: What other values are 'permissible'?
The upper and lower bounds of any other object that contains u.
> >> Or what if the union has its own 'operator new' that returns elements
> >> from one static array of unions?
> >> We now suddenly have another array to consider, which might or might
> >> now change start_area and after_area.
> >
> >The contents of the pointer are manipulated by the imlementation, not by
> >your operator new. The implementation would set start_area to point to
> >the start of the largest enclosing object, and end_area to point one
> >past the end of it. The net result could be that pointers could compare
> >equal, if one points to the beginning of one object, and the other
> >points one-past-the-end of a seperately allocated object.
>
> I interpret this as saying that 'new' takes the result of 'operator new'
> and sets 'start_area' and 'end_area' to limits of the allocated
> object.
That's not what I meant, though it's possible. It's also possible for
'operator new' to allocate all of its memory from a single large static
array. In that case, every pointer operator new returns will have
start_area and end_area pointing to the beginning and one past the end
of that large static array. They will be allowed to compare equal,
because they are all parts of a single object, that static 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: markw65@my-dejanews.com
Date: 1998/11/27 Raw View
In article <73j91m$rlu$1@news.lth.se>,
Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
> In article <365B6778.9D62B8E8@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
> >> union U{
> >> int arr1[1];
> >> int arr9[9];
> >> } u;
> >>
> >> Since pointers are random access iterators and u.arr9==u.arr1 it seems
> >> to follow that u.arr9+1==u.arr1+1.
> >
> >Yes, both pointers would have start_area == &u and after_area==u.ar9+9.
>
> That was not clear to me, and in a different thread someone mentioned
> a compiler that from 'void f(int (&x)[1],int i) { x[i];}'
> could conclude that i=0. This seems to contradict your assertion,
> and I would like to know how the standard handles this situation.
>
I suspect you are talking about one of my posts, and you are taking it too
far.
int x[1];
void f1(int i) { x[i]; } // compiler can assume i == 0
void f2(int (&x)[1],int i) { x[i];} // compiler cant assume anything.
// (unless of course it can do sufficient static, interprocedural analysis)
>And how about:
>union U {
> int arr1[1];
> int arr2[2][1];
> int arr9[9];
>} u;
>What are start_area and after_area for arr2[0] and arr2[1]?
You are missing the point... all pointers have to originate (at runtime) from
a memory allocation function, or from the adress of an actual declared
object. The start_area is always the start of the declared object, or the
address returned by the allocation function. after_area is the end of the
object (or allocated memory).
So any pointer into u has its start_area set to &u, and its after_area set to
&u+1. Actually, with some unions, you could do better. after_area for a
member m only has to point to the end of the largest member whose initial
sequence matches m.
eg
union U {
int i[3];
int j[4];
float k[6];
};
after_area for i & j could be as low as &j[4], and for k could be &k[6].
Mark Williams
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/28 Raw View
Hans Olsson wrote:
>
> In article <365B6778.9D62B8E8@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
> >
> >Hans Olsson wrote:
....
> How could you create a structure/object with less strict alignment
> than its members?
You're right - I hadn't thought that through.
>
> >....
> >> If you think they are well-defined consider the following examples
> >> union U{
> >> int arr1[1];
> >> int arr9[9];
> >> } u;
> >>
> >> Since pointers are random access iterators and u.arr9==u.arr1 it seems
> >> to follow that u.arr9+1==u.arr1+1.
> >
> >Yes, both pointers would have start_area == &u and after_area==u.ar9+9.
> That was not clear to me, and in a different thread someone mentioned
> a compiler that from 'void f(int (&x)[1],int i) { x[i];}'
> could conclude that i=0. This seems to contradict your assertion,
> and I would like to know how the standard handles this situation.
It says that the '1' in that declaration is irrelevant; it that context
[1] is equivalent to []. Let's consider a case where you have an actual
array of known length, rathter than a pointer:
int x[1];
int y = x[i];
An implementation is allowed to assume that i==0. The key difference is
that x[i] dereferences the pointer, allowing undefined behavior; one of
the infinity of allowed undefined behaviors would be to treat x[i] as
identical to x[0].
Comparison of pointers of the same type for equality is always defined.
> And how about:
>
> union U {
> int arr1[1];
> int arr2[2][1];
> int arr9[9];
> } u;
>
> What are start_area and after_area for arr2[0] and arr2[1]?
It's permissible to set them both to &u and &u+1.
> Or what if the union has its own 'operator new' that returns elements
> from one static array of unions?
> We now suddenly have another array to consider, which might or might
> now change start_area and after_area.
The contents of the pointer are manipulated by the imlementation, not by
your operator new. The implementation would set start_area to point to
the start of the largest enclosing object, and end_area to point one
past the end of it. The net result could be that pointers could compare
equal, if one points to the beginning of one object, and the other
points one-past-the-end of a seperately allocated object. This doesn't
violate the interpretation of the standard which I'm disputing, because
it is the full object which determines how the pointers should be
compared for equality, not the smallest containing object.
> >> The standard seem to make comparisons between pointers to elements
> >> in one array and one-past-end of another array legal and defined.
> >>
> >> I doubt that was the intention or that compiler vendors will implement
> >> this.
> >
> >Why not? Historically many implementions have supported such
> >comparisons.
>
> They have supported the comparisons, but the results are not always
> well-defined, i.e. the pointer to one array and one-past-end of another
> might or might not compare equal depending on how the arrays are
> allocated.
The result of an equality comparison is very well defined: to paraphrase
it, the pointers compare equal if and only if they point to the same
thing. All null pointers are treated as pointing at the same non-thing.
All pointers pointing one past the end of an array are treated as
pointing at the same thing, which might not actually exist.
Whether or not the pointers point at the same thing depends upon the
implementation, but that's a different issue. Whether two things are the
same is not something an implementation can decide arbitrarily: if they
are both derefencable, you must always get the same result from
dereferencing either pointer. Therefore, the only freedom of
interpretation the implementation has is with regard to pointers that
aren't dereferencable, such as pointers to one past the end of an 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/28 Raw View
In article <73k59b$bst$1@nnrp1.dejanews.com>, <markw65@my-dejanews.com> wrote:
>In article <73j91m$rlu$1@news.lth.se>,
> Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
>> That was not clear to me, and in a different thread someone mentioned
>> a compiler that from 'void f(int (&x)[1],int i) { x[i];}'
>> could conclude that i=0. This seems to contradict your assertion,
>> and I would like to know how the standard handles this situation.
>>
>
>I suspect you are talking about one of my posts, and you are taking it too
>far.
It was your post, but I'm not sure if I take it too far.
>int x[1];
>void f1(int i) { x[i]; } // compiler can assume i == 0
>
>void f2(int (&x)[1],int i) { x[i];} // compiler cant assume anything.
>// (unless of course it can do sufficient static, interprocedural analysis)
But your post (titled "Re: Minimum Size of Array in Standard" 1998-11-10)
had the following example:
struct varstruct {unsigned int num_elements;int elements[1];};
void f(struct varstruct*p);
p->element[i]; // One C++-Compiler deduces that i=0.
If we erase 'num_elements' it is the same situation as we have now
with the unions (a member of a POD-union is allocated as though it were
the sole member of a POD-struct).
Having 'num_elements' does not change anything unless
the compiler adds extra padding between unsigned int and int[]-arrays,
and this padding depends on the number of elements in the array!
struct var1 {
unsigned int num_elements;
int elements[1];
};
struct var9 {
unsigned int num_elements;
int elements[9];
};
char*c=new char[sizeof(struct var1)+sizeof(struct var9)];
assert(offsetof(struct var1,elements)==offsetof(struct var9,elements));
struct var1*p1=static_cast<struct var1*>(c);
struct var9*p9=static_cast<struct var9*>(c);
If there is no padding (or the same padding) the assertion will not fail
and p1->elements+0 and p9->elements+0 does in that case point to the
same object, and I can't see anything illegal about p1->elements[4].
>>union U {
>> int arr1[1];
>> int arr2[2][1];
>> int arr9[9];
>>} u;
>
>>What are start_area and after_area for arr2[0] and arr2[1]?
>
>You are missing the point... all pointers have to originate (at runtime) from
>a memory allocation function, or from the adress of an actual declared
>object. The start_area is always the start of the declared object, or the
>address returned by the allocation function. after_area is the end of the
>object (or allocated memory).
I would call that contrary to the spirit of C/C++ because you are
allowed to write your own memory-allocator (including global operator new),
but you have no way of setting start_area and after_area for them.
And I still haven't seen any clear rules about the values of
start_area and after_area with references to the standard.
Furthermore if start_area and after_area are the same for arr2[0] and
arr2[1] we have two arrays such that the end-plus-one of arr2[0]
is identical to the start of arr2[1] (there cannot be padding since
the size of an array is the number of elements*size of element).
I'm not sure that was idea of the original poster.
>So any pointer into u has its start_area set to &u, and its after_area set to
>&u+1. Actually, with some unions, you could do better. after_area for a
>member m only has to point to the end of the largest member whose initial
>sequence matches m.
>
>eg
>union U {
>int i[3];
>int j[4];
>float k[6];
>};
>
>after_area for i & j could be as low as &j[4], and for k could be &k[6].
Unless the union was within another union, or it was allocated
with global operator new/malloc/new char[].
Disclaimer: This is all based on my incomplete understanding of the standard.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: markw65@my-dejanews.com
Date: 1998/11/29 Raw View
In article <73p1sc$dfs$1@news.lth.se>,
Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
>
> In article <73k59b$bst$1@nnrp1.dejanews.com>, <markw65@my-dejanews.com> wrote:
> >In article <73j91m$rlu$1@news.lth.se>,
> > Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
> >> That was not clear to me, and in a different thread someone mentioned
> >> a compiler that from 'void f(int (&x)[1],int i) { x[i];}'
> >> could conclude that i=0. This seems to contradict your assertion,
> >> and I would like to know how the standard handles this situation.
> >>
> >
> >I suspect you are talking about one of my posts, and you are taking it too
> >far.
>
> It was your post, but I'm not sure if I take it too far.
>
> >int x[1];
> >void f1(int i) { x[i]; } // compiler can assume i == 0
> >
> >void f2(int (&x)[1],int i) { x[i];} // compiler cant assume anything.
> >// (unless of course it can do sufficient static, interprocedural analysis)
>
> But your post (titled "Re: Minimum Size of Array in Standard" 1998-11-10)
> had the following example:
>
> struct varstruct {unsigned int num_elements;int elements[1];};
> void f(struct varstruct*p);
> p->element[i]; // One C++-Compiler deduces that i=0.
But it is _very_ different. A pointer or reference to an array could be
referring to a part of a larger array:
int x[10][1];
int (&px)[1] = x[3];
// px[-3] through px[6] are all valid.
On the other hand a member of a structure cannot refer to anything but an
object of the declared type of the member (other than via reinterpret_cast or
some other implementation defined mechanism).
> If we erase 'num_elements' it is the same situation as we have now
> with the unions (a member of a POD-union is allocated as though it were
> the sole member of a POD-struct).
Yes, and it still doesnt change anything...
> Having 'num_elements' does not change anything unless
> the compiler adds extra padding between unsigned int and int[]-arrays,
> and this padding depends on the number of elements in the array!
>
> struct var1 {
> unsigned int num_elements;
> int elements[1];
> };
> struct var9 {
> unsigned int num_elements;
> int elements[9];
> };
> char*c=new char[sizeof(struct var1)+sizeof(struct var9)];
> assert(offsetof(struct var1,elements)==offsetof(struct var9,elements));
> struct var1*p1=static_cast<struct var1*>(c);
> struct var9*p9=static_cast<struct var9*>(c);
But that is implementation defined behaviour. Are those static_casts even
legal?
> If there is no padding (or the same padding) the assertion will not fail
> and p1->elements+0 and p9->elements+0 does in that case point to the
> same object, and I can't see anything illegal about p1->elements[4].
Not illegal, just implementation defined. In my implementation p1->elements[4]
refers to p1->elements[0].
> >>union U {
> >> int arr1[1];
> >> int arr2[2][1];
> >> int arr9[9];
> >>} u;
> >
> >>What are start_area and after_area for arr2[0] and arr2[1]?
> >
> >You are missing the point... all pointers have to originate (at runtime) from
> >a memory allocation function, or from the adress of an actual declared
> >object. The start_area is always the start of the declared object, or the
> >address returned by the allocation function. after_area is the end of the
> >object (or allocated memory).
>
> I would call that contrary to the spirit of C/C++ because you are
> allowed to write your own memory-allocator (including global operator new),
> but you have no way of setting start_area and after_area for them.
_You_ dont, but the compiler certainly does. I would argue that the compiler
is entitled to set them whenever it sees a new (user defined or otherwise).
But even if you disagree, somewhere in the bowels of your allocation
functions, you have to resort to the standard allocation functions, or
allocate from some pre-declared object - typically an array of char. And
those allocations will have the start_area and after_area defined. So you
just get somewhat looser bounds.
> And I still haven't seen any clear rules about the values of
> start_area and after_area with references to the standard.
start_area and after_area are not mentioned by the standard. They are a
possible mechanism for implementing a possible interpretation of the standard
without introducing padding between objects of the same type.
> Furthermore if start_area and after_area are the same for arr2[0] and
> arr2[1]
They are not. As James as said repeatedly, they point to the start and end of
the top-level object. I would change that to the "complete array containing
the object" (where a non-array object is treated as an array of one element).
Which gives better bounds in the case of structures (but needs some special
casing for unions with members which share common initial elements).
> we have two arrays such that the end-plus-one of arr2[0]
> is identical to the start of arr2[1] (there cannot be padding since
> the size of an array is the number of elements*size of element).
>
> I'm not sure that was idea of the original poster.
>
> >So any pointer into u has its start_area set to &u, and its after_area set to
> >&u+1. Actually, with some unions, you could do better. after_area for a
> >member m only has to point to the end of the largest member whose initial
> >sequence matches m.
> >
> >eg
> >union U {
> >int i[3];
> >int j[4];
> >float k[6];
> >};
> >
> >after_area for i & j could be as low as &j[4], and for k could be &k[6].
>
> Unless the union was within another union, or it was allocated
> with global operator new/malloc/new char[].
The example given is not inside another union. If you want to change your
example, I will change my response. Being allocated by operator new etc doesnt
change anything.
Mark Williams
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/26 Raw View
In article <365B6778.9D62B8E8@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
>Hans Olsson wrote:
[...]
>I was thinking more in terms of
>
> void *start_area;
> ptrdiff_t offset;
>
>After all, the start_area for an object might not be suitably aligned
>for a T*; it could be the start of a structure or union containing a T.
>The after_area would be needed only for bounds checking, which was not
>what I was talking about.
How could you create a structure/object with less strict alignment
than its members?
>....
>> If you think they are well-defined consider the following examples
>> union U{
>> int arr1[1];
>> int arr9[9];
>> } u;
>>
>> Since pointers are random access iterators and u.arr9==u.arr1 it seems
>> to follow that u.arr9+1==u.arr1+1.
>
>Yes, both pointers would have start_area == &u and after_area==u.ar9+9.
That was not clear to me, and in a different thread someone mentioned
a compiler that from 'void f(int (&x)[1],int i) { x[i];}'
could conclude that i=0. This seems to contradict your assertion,
and I would like to know how the standard handles this situation.
And how about:
union U {
int arr1[1];
int arr2[2][1];
int arr9[9];
} u;
What are start_area and after_area for arr2[0] and arr2[1]?
Or what if the union has its own 'operator new' that returns elements
from one static array of unions?
We now suddenly have another array to consider, which might or might
now change start_area and after_area.
>> The standard seem to make comparisons between pointers to elements
>> in one array and one-past-end of another array legal and defined.
>>
>> I doubt that was the intention or that compiler vendors will implement
>> this.
>
>Why not? Historically many implementions have supported such
>comparisons.
They have supported the comparisons, but the results are not always
well-defined, i.e. the pointer to one array and one-past-end of another
might or might not compare equal depending on how the arrays are
allocated.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/25 Raw View
Hans Olsson wrote:
>
> In article <365A4450.B0B22A61@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
....
> I must have been unclear,the suggestion I'm discussing sees a pointer
> as the following data-structure:
>
> template <class T> struct pointer {
> T*real_ptr; // The object is located here.
> T*start_area; // Start of area in which 'real_ptr' can be located.
> T*after_area; // End-plus-one of area in which 'real_ptr' can be located.
> /* Possibly without after_area */
I was thinking more in terms of
void *start_area;
ptrdiff_t offset;
After all, the start_area for an object might not be suitably aligned
for a T*; it could be the start of a structure or union containing a T.
The after_area would be needed only for bounds checking, which was not
what I was talking about.
....
> If you think they are well-defined consider the following examples
> union U{
> int arr1[1];
> int arr9[9];
> } u;
>
> Since pointers are random access iterators and u.arr9==u.arr1 it seems
> to follow that u.arr9+1==u.arr1+1.
Yes, both pointers would have start_area == &u and after_area==u.ar9+9.
....
> The standard seem to make comparisons between pointers to elements
> in one array and one-past-end of another array legal and defined.
>
> I doubt that was the intention or that compiler vendors will implement
> this.
Why not? Historically many implementions have supported such
comparisons. Certainly the simple model of a pointer as an offset in a
single linear address space supports such comparisons.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/24 Raw View
In article <3654A043.41C6@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
>Hans Olsson wrote:
>> Two problems:
>>
>> 1. Is this allowed by the standard?
>
>What part of the standard do you think it violates?
The standard says:
Two pointer shall compare equal if they both point to the same object
(or both point one past end of the same array).
The problem:
A pointer to one past end of one array might point to another object,
unless we pad. We do not want to pad (int a[2][3];)and comparison between
one-past-end and other arrays should not be defined.
One "cure" for this suggested in this thread:
Two pointer shall compare equal if they both point to the same object
and the pointers point to the same area.
To me this looked like the "cure" was not legal according to the standard.
Furthermore it would require a definition of the area into which
the pointer points, which is not defined in the standard.
It could be that there exists a definition of this area that does
not violate the standard, but that's not been proven.
The simplest solution to the original problem is to admit that the standard
needs to be revised for operator== and the less-template for pointers.
operator== should be defined for comparison between:
* pointers to objects and the null-pointer (in all combinations).
* pointers to elements in an array, one-past-end of the same array
and the null-pointer (in all combinations).
The less-template for pointers should be a total ordering if the
elements either are
* pointers to elements in an array and one-past-end of the same array
and the null-pointer.
or
* pointers to objects and the null-pointer.
>The debate so far
>has been about whether it's required by the standard, not about whether
>it was allowed.
Correct, but before proving that it is required we should establish that
it is legal.
>> 2. What about the following code?
>>
>> int x[10];
>> int *y=&(x[0]);
>> int *end=y+10; // Is this legal?
>
>Yes. Why not?
A non-array object is for operator+ treated as a pointer to an array
of length 1, and adding 10 to a pointer into an array of length 1 is
undefined. Of course we know that x[0] is an object of an array,
but if this were sent as a reference to some other function it would not
be immediately obvious.
This means that not only pointers but also references must carry
information about what area the reference is located in.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/24 Raw View
Hans Olsson wrote:
>
> In article <3654A043.41C6@wizard.net>, James Kuyper <kuyper@wizard.net> wrote:
> >Hans Olsson wrote:
> >> Two problems:
> >>
> >> 1. Is this allowed by the standard?
> >
> >What part of the standard do you think it violates?
>
> The standard says:
> Two pointers shall compare equal if they both point to the same object
> (or both point one past end of the same array).
Which isn't violated by that implementation.
> The problem:
> A pointer to one past end of one array might point to another object,
> unless we pad. We do not want to pad (int a[2][3];)and comparison between
No. In the implementation I was describing, a pointer that is one past
the end of an array does not point to the first item of the next array,
even though that object is directly adjacent with no padding. Of course,
if you dereference that pointer, you'll get undefined behavior. The
undefined behavior you'll get is that you'll be dereferencing the first
part of the next array.
> one-past-end and other arrays should not be defined.
Why not? Historically, on most implementations, it is.
> One "cure" for this suggested in this thread:
> Two pointer shall compare equal if they both point to the same object
> and the pointers point to the same area.
That's not a cure; that's a sloppy way of saying pretty much exactly
what one part of the standard already says.
> To me this looked like the "cure" was not legal according to the standard.
Why? That was my original question.
> Furthermore it would require a definition of the area into which
> the pointer points, which is not defined in the standard.
That's implementation defined. That's what's called the value of a
pointer. The bit pattern in a pointer is merely it's representation;
it's value is the area into which the pointer points.
> It could be that there exists a definition of this area that does
> not violate the standard, but that's not been proven.
What aspect of the standard do you think it might violate?
> The simplest solution to the original problem is to admit that the standard
> needs to be revised for operator== and the less-template for pointers.
>
> operator== should be defined for comparison between:
> * pointers to objects and the null-pointer (in all combinations).
> * pointers to elements in an array, one-past-end of the same array
> and the null-pointer (in all combinations).
That's no change.
> The less-template for pointers should be a total ordering if the
> elements either are
> * pointers to elements in an array and one-past-end of the same array
> and the null-pointer.
> or
> * pointers to objects and the null-pointer.
On many implmentations, it would be difficult to impose a total ordering
on pointers to different objects, including null pointers.
> >The debate so far
> >has been about whether it's required by the standard, not about whether
> >it was allowed.
>
> Correct, but before proving that it is required we should establish that
> it is legal.
Identify the illegality, please?
> >> 2. What about the following code?
> >>
> >> int x[10];
> >> int *y=&(x[0]);
> >> int *end=y+10; // Is this legal?
> >
> >Yes. Why not?
>
> A non-array object is for operator+ treated as a pointer to an array
Not quite; a pointer to a non-array object is treated that way; no such
pointers occur in this code sample. &x[0] is a pointer to an array, and
so is 'y'.
> of length 1, and adding 10 to a pointer into an array of length 1 is
> undefined. Of course we know that x[0] is an object of an array,
> but if this were sent as a reference to some other function it would not
> be immediately obvious.
>
> This means that not only pointers but also references must carry
> information about what area the reference is located in.
Of course; a 'T&' is usually implemented internally (when not optimized
away) as the functional equivalent of a 'T *const'.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/24 Raw View
In article <365A4450.B0B22A61@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>Hans Olsson wrote:
>> One "cure" for this suggested in this thread:
>> Two pointer shall compare equal if they both point to the same object
>> and the pointers point to the same area.
>
>That's not a cure; that's a sloppy way of saying pretty much exactly
>what one part of the standard already says.
The second half should have said 'and the pointers point to objects
located in the same area of memory'.
The standard says the same without 'and the pointers point to objects
located in the same area of memory', and does not even (AFAIK) define
these areas.
>> To me this looked like the "cure" was not legal according to the standard.
>
>Why? That was my original question.
It might seem as two pointers that point to the same object might compare
unequal.
>> Furthermore it would require a definition of the area into which
>> the pointer points, which is not defined in the standard.
>
>That's implementation defined. That's what's called the value of a
>pointer.
I must have been unclear,the suggestion I'm discussing sees a pointer
as the following data-structure:
template <class T> struct pointer {
T*real_ptr; // The object is located here.
T*start_area; // Start of area in which 'real_ptr' can be located.
T*after_area; // End-plus-one of area in which 'real_ptr' can be located.
/* Possibly without after_area */
bool operator==(const pointer<T>&x) {
return (real_ptr==x.real_ptr)&&(start_area==x.start_area)&&
(after_area==x.after_area);
}
/* Or perhaps:
bool in_area() const {
return (real_ptr>=start_area)&&(real_ptr<after_area);
}
bool operator==(const pointer<T>&x) {
return (in_area()==x.in_area())&&(real_ptr==x.real_ptr);
}
*/
};
The members start_area and after_area are not mentioned in the
standard (unless I've missed them or it was changed from CD2),
but they influence the behaviour of the program.
If you think they are well-defined consider the following examples
union U{
int arr1[1];
int arr9[9];
} u;
Since pointers are random access iterators and u.arr9==u.arr1 it seems
to follow that u.arr9+1==u.arr1+1.
There are also other strange examples:
struct {
char ch[2];
POD_TYPE t;
} x;
for(char*p=x.ch;p!=(char*)((&x)+1);p++);
If the intention of the standard were to make such codes illegal,
it could have done so by defining the area into which the pointer
points (and not merely the object to which it points).
It would probably have been messy (casts would have been fun!)
>> The simplest solution to the original problem is to admit that the standard
>> needs to be revised for operator== and the less-template for pointers.
>>
>> operator== should be defined for comparison between:
>> * pointers to objects and the null-pointer (in all combinations).
>> * pointers to elements in an array, one-past-end of the same array
>> and the null-pointer (in all combinations).
>
>That's no change.
The change would be to not define the other pointer comparisons
(if they are undefined/implementation-defined/... is less important).
The standard seem to make comparisons between pointers to elements
in one array and one-past-end of another array legal and defined.
I doubt that was the intention or that compiler vendors will implement
this.
>> The less-template for pointers should be a total ordering if the
>> elements either are
>> * pointers to elements in an array and one-past-end of the same array
>> and the null-pointer.
>> or
>> * pointers to objects and the null-pointer.
>
>On many implmentations, it would be difficult to impose a total ordering
>on pointers to different objects, including null pointers.
The less-template is now required to create a total ordering for pointers
without any restriction.
Requiring less cannot possibly be a problem.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Barry Margolin <barmar@bbnplanet.com>
Date: 1998/11/20 Raw View
In article <731ma3$50u$1@news.lth.se>,
Hans Olsson <Email_To::.Hans.Olsson@dna.lth.se> wrote:
>Two problems:
>
>1. Is this allowed by the standard?
>
>2. What about the following code?
>
>int x[10];
>int *y=&(x[0]);
>int *end=y+10; // Is this legal?
>
>The problem is if '&(x[0])' is a pointer to an element of an array
>(as would seem logical) or a pointer to a single object
>(we do take the address of a single object).
I believe a distinction needs to be made between independent objects and
objects that are both subobjects of the same object. When deciding whether
you're allowed to compare two pointers, the object that matters is the
highest level object. Thus, in:
struct {
int a[10];
int b[10];
} x;
it's permissible to compare &(x.a[10]) == &(x.b[0]), and in most
implementations this will evaluate to 1. I believe there are also
requirements that subobjects in a POD struct have increasing addresses, so
that &x.a<&x.b is permitted, and required to evaluate to 1.
--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/20 Raw View
Hans Olsson wrote:
>
> In article <F2o8ny.5Lu@cadlab.it>, Alex Martelli <martelli@cadlab.it> wrote:
> >I think James is right, that is, what would be needed would be
> >just to have, "as part of [each] pointer", the "indication of the
> >object [into which] it points", rather than the potentially vaster
> >amount of information needed to "store the way [it] was
> >calculated".
>
> Two problems:
>
> 1. Is this allowed by the standard?
What part of the standard do you think it violates? The debate so far
has been about whether it's required by the standard, not about whether
it was allowed.
> 2. What about the following code?
>
> int x[10];
> int *y=&(x[0]);
> int *end=y+10; // Is this legal?
Yes. Why not?
> The problem is if '&(x[0])' is a pointer to an element of an array
> (as would seem logical) or a pointer to a single object
> (we do take the address of a single object).
It is a pointer to an element of an array. It is also a pointer into a
single array object. I don't see the problem.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/11/20 Raw View
David Abrahams wrote:
>> I see why the standard *seems* to require padding between arrays, but
>> I'm not sure that it in fact does. Since I've heard this perception
>> before, I think a clarifying remark in teh standard may be in order.
>>
>> int i[1];
>> int j[1];
>>
>> On many implementations, i+1 == j.
>>
>> Now let's ask the question: is this strictly conforming?
>> I say yes:
>> i+1 and j are pointers of the same type, so we have to ask: do they
>> satisfy any of the requirements that are OR'd together above
>> a. they are both null (NO)
>> b. both point to the same object or function (YES: j[0])
>> c. both point one past the end of the same array (YES: i+1)
David R Tribble <david.tribble@central.beasys.com> wrote:
>> Yes, it's conforming. But implementations where 'i+1 != j' are
>> also conforming.
David Abrahams wrote:
> Of course, but so what? All you prove by saying that is that an
> implementation is allowed to lay out i and j any way it likes: with or
> without padding, in any order at all, so long as i != j.
Yes, and that's the point. Padding bytes between objects are not
implied nor needed. Some people think the standard implies that
padding is required, but the conforming examples above prove that
it doesn't. (Interpreting the standard as requiring padding
between objects would make one of our examples nonconforming.)
-- David R. Tribble, dtribble@technologist.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/21 Raw View
In article <qJ052.66$Ki.497811@burlma1-snr1.gtei.net>, Barry Margolin
<barmar@bbnplanet.com> writes
>it's permissible to compare &(x.a[10]) == &(x.b[0]), and in most
>implementations this will evaluate to 1. I believe there are also
>requirements that subobjects in a POD struct have increasing addresses, so
>that &x.a<&x.b is permitted, and required to evaluate to 1.
It is always permissable to compare two valid addresses for identity.
The question is when is an implementation permitted to return true. We
know when it is required to return true, and we know times when it must
return false. However there is a soft spot because the same address can
be shared in some circumstances, is true allowed in those cases?
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: abrahams@spam.motu.com (David Abrahams)
Date: 1998/11/18 Raw View
On 18 Nov 98 15:47:06 GMT, David R Tribble
<david.tribble@noSPAM.central.beasys.com> wrote:
>David Abrahams wrote:
>> I see why the standard *seems* to require padding between arrays, but
>> I'm not sure that it in fact does. Since I've heard this perception
>> before, I think a clarifying remark in teh standard may be in order.
>>
>> int i[1];
>> int j[1];
>>
>> On many implementations, i+1 == j.
>>
>> Now let's ask the question: is this strictly conforming?
>> I say yes:
>> i+1 and j are pointers of the same type, so we have to ask: do they
>> satisfy any of the requirements that are OR'd together above
>> a. they are both null (NO)
>> b. both point to the same object or function (YES: j[0])
>> c. both point one past the end of the same array (YES: i+1)
>
>Yes, it's conforming. But implementations where 'i+1 != j' are
>also conforming.
Of course, but so what? All you prove by saying that is that an
implementation is allowed to lay out i and j any way it likes: with or
without padding, in any order at all, so long as i != j.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/18 Raw View
In article <3651B679.D89F3DCB@prolifics.com>, Hyman Rosen
<hymie@prolifics.com> writes
>It works just fine if you require that every array has a pad byte
>separating
>it from the next object. Then pointers don't need to keep track of how they
>were made. (There is no one-past-the-end pointer for non-arrays.)
>
>In any case, I've come around to the non-mutually-exclusive point of view,
>so I no longer have any problem with a pointer which is simultaneously a
>pointer to an object and a pointer to one past the end of an array.
Adding a pad byte is an illusion. If you are to enforce the rule as
some seem to interpret it pointers must store information about the
object pointed to as well as the location within it being addressed.
Else how will the following code work:
bool fn(char* ptr1, char* ptr2, int n) {
return (ptr1 + n) == ptr2;
}
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Alex Martelli" <martelli@cadlab.it>
Date: 1998/11/19 Raw View
Francis Glassborow wrote in message ...
>In article <365050AF.41C6@wizard.net>, James Kuyper <kuyper@wizard.net>
>writes
>>If markw's interpretation is correct, then any implementation that
>>allocates objects contiguously would have to include an indication of
>>the object pointed to as part of the pointer, and use that indicator
>>whenever comparing pointers for equality.
>
>Sorry that does not work unless you require that all pointers store the
>way they were calculated. Consider
I think James is right, that is, what would be needed would be
just to have, "as part of [each] pointer", the "indication of the
object [into which] it points", rather than the potentially vaster
amount of information needed to "store the way [it] was
calculated".
To see this, imagine a "pointer" is stored as two addresses:
template <typename T>
struct __pointer {
void* pObject; // need not be a T*
T* pCurrent;
_pointer(void* p1, T* p2):
pObject(p1), pCurrent(p2) {}
// etc
};
template <typename T> inline
__pointer<T> operator+(_pointer<T> p, int i) {
return __pointer<T>(p.pObject, i+p.pCurrent);
}
template <typename A, typename B> inline
bool operator==(_pointer<A> pa, __pointer<B> pb) {
return (pa.pObject==pb.pObject) &&
(pa.pCurrent==pb.pCurrent);
}
// etc
Now, let's "translate" your code into this, like a compiler
implemented as a preprocessor might:
>int a[10]
>int * p = a;
__pointer<int> p = {a, a};
>int i,j;
>
>int * fn(int * ptr) { return ptr+12;}
_pointer<int> fn(_pointer<int> p) {
return _pointer<int>(p.pObject,12+p.pCurrent);
}
>
>int main() {
> cout << ((&i == fn(a)) ? "true " : "false");
The operation would become:
&i, turned into a __pointer<int>, is {&i, &i};
a, turned ditto, is {&a[0], &a[0]};
fn(a) gives {&a[0], &a[12]}; // the latter is illegal...!
operator== returns false (because of the
difference in the pObject members)
>How do you propose that an implementation detect that the return value
>from fn() does not meet the constraints given? If you are going to
Exactly as James wrote, one way to do so is for the
implementation to record _two_ addresses for each
"pointer".
>require that this program always output 'false' then every existing
>implementation of C and C++ is broken and no one would want to use one
>that wasn't.
I agree -- if the C++ standard mandated such an implementation,
then, suddenly, C++ would become seriously handicapped in doing
low-level work, because of the overhead in space and time that it
implies for any work at all with these "extended" pointers.
However, I, for one, would love having such an implementation
available as a _debug_ one -- of course, one might then as well
take the little extra trouble to record lowest _and_ highest valid
addresses between which a pointer can roam, and give very
clear diagnostics of any error in pointer arithmetic, etc.
I suspect the rarity of such debug-implementation is partly due
to the difficulty of mixing object files and libraries compiled with
such a pointer representation, with ones compiled in non-debug
mode, with "pointer" represented by one (1) address, and no
possible checking; "all-or-nothing" versions of debug modes do
not tend to be very popular, nor widely used, for obvious reasons.
Alex
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/19 Raw View
In article <F2o8ny.5Lu@cadlab.it>, Alex Martelli <martelli@cadlab.it> wrote:
>I think James is right, that is, what would be needed would be
>just to have, "as part of [each] pointer", the "indication of the
>object [into which] it points", rather than the potentially vaster
>amount of information needed to "store the way [it] was
>calculated".
Two problems:
1. Is this allowed by the standard?
2. What about the following code?
int x[10];
int *y=&(x[0]);
int *end=y+10; // Is this legal?
The problem is if '&(x[0])' is a pointer to an element of an array
(as would seem logical) or a pointer to a single object
(we do take the address of a single object).
[...]
>However, I, for one, would love having such an implementation
>available as a _debug_ one -- of course, one might then as well
>take the little extra trouble to record lowest _and_ highest valid
>addresses between which a pointer can roam, and give very
>clear diagnostics of any error in pointer arithmetic, etc.
Me too:-)
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/17 Raw View
markw65@my-dejanews.com wrote:
...
> But I think I noticed another problem with that if and only if.
>
> char *x = new char[10];
> char *y = x;
>
> delete [] x;
>
> ...
>
> if (x == y) {
> ...
> }
...
> Ok. What did I miss?
Section 3.7.3: "If the argument given to a deallocation function in the
standard library is a pointer that is not the null pointer value (4.10),
the deallocation function shall deallocate the storage referenced by the
pointer, rendering invalid all pointers referring to any part of the
deallocated storage. The effect of using an invalid pointer value
(including passing it to a deallocation function) is undefined."
Therefore, every use you made of x after calling delete has undefined
effects. Anything is allowed, including having x==y be true.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1998/11/18 Raw View
Francis Glassborow wrote:
> Sorry that does not work unless you require that all pointers store the
> way they were calculated.
It works just fine if you require that every array has a pad byte
separating
it from the next object. Then pointers don't need to keep track of how they
were made. (There is no one-past-the-end pointer for non-arrays.)
In any case, I've come around to the non-mutually-exclusive point of view,
so I no longer have any problem with a pointer which is simultaneously a
pointer to an object and a pointer to one past the end of an 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/18 Raw View
David R Tribble wrote:
>
> Mark Williams <markw65@my-dejanews.com> wrote:
> >> On the other hand, given
> >> int i;
> >> int j;
> >>
> >> &i+1 and &j do not refer to the same object, and so may not compare
> >> equal.
>
> David Abrahams wrote:
> > Au contraire, nothing in the standard forbids &i+1 and &j from
> > referring to the same object, and so on any given implementation they
> > are allowed compare equal.
>
> Mark obviously meant to say that the addresses "might not compare
> equal." So you're both right.
That's not obvious to me. It's consistent with his argument that he said
exactly what he meant; that they're not allowed to compare equal.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/18 Raw View
In article <72s0ks$no6$1@nnrp1.dejanews.com>, markw65@my-dejanews.com
writes
>In fact, given an arbitrary pointer:
>
>if (x && x == x && x + 1 == x + 1) {
>// it is safe to dereference x here :-)
>}
I do not follow your logic, surely x == x is always true? And x+1 == x+1
is always true, so the truth value of the conditional depends on the
truth value of x. While x converting to false certainly means you can
dereference it why should it being true say anything.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/11/18 Raw View
David Abrahams wrote:
> I see why the standard *seems* to require padding between arrays, but
> I'm not sure that it in fact does. Since I've heard this perception
> before, I think a clarifying remark in teh standard may be in order.
>
> int i[1];
> int j[1];
>
> On many implementations, i+1 == j.
>
> Now let's ask the question: is this strictly conforming?
> I say yes:
> i+1 and j are pointers of the same type, so we have to ask: do they
> satisfy any of the requirements that are OR'd together above
> a. they are both null (NO)
> b. both point to the same object or function (YES: j[0])
> c. both point one past the end of the same array (YES: i+1)
Yes, it's conforming. But implementations where 'i+1 != j' are
also conforming.
Comparing the address of the object at i+1 to the address of the
object at j is implementation-defined behavior, because
a. they are both not null,
b. they might or might not point to the same object,
c. they might or might not both point past the end of the same
array.
The last point is important; the object pointed to by i+1 is one
past the end of the i array, while the object pointed to by j
resides in the j array. It's a minor distinction, but an important
one: i+0 and i+1 are considered pointers into the i array, while
j+0 and j+1 are considered pointers into a completely different
array. (This makes a more substantial difference on
segmented-address architectures than linear-address architectures.)
Comparing pointers to two different arrays is certainly legal (and
sometimes useful), but yields implementation-defined results.
-- David R. Tribble, dtribble@technologist.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Barry Margolin <barmar@bbnplanet.com>
Date: 1998/11/14 Raw View
In article <364c7a19.265612481@news.motu.com>,
David Abrahams <abrahams@spam.motu.com> wrote:
>I see why the standard *seems* to require padding between arrays, but
>I'm not sure that it in fact does. Since I've heard this perception
>before, I think a clarifying remark in teh standard may be in order.
>
>int i[1];
>int j[1];
>
>On many implementations, i+1 == j.
>
>Now let's ask the question: is this strictly conforming?
>I say yes:
>i+1 and j are pointers of the same type, so we have to ask: do they
>satisfy any of the requirements that are OR'd together above
>a. they are both null (NO)
>b. both point to the same object or function (YES: j[0])
>c. both point one past the end of the same array (YES: i+1)
The notion "point to the same object" should be taken in the context of the
abstract machine. i+1 points to, or one past the end of, the object i, j
points to, or one past the end of, the object j. Thus, you are not
permitted to compare them.
If the constraint on comparing pointers were dependent on physical layout,
it would be nonsensical. "Strictly conforming" is supposed to be a quality
of code that's independent of implementations. But by your reasoning, the
expression is strictly conforming only because your implementation happens
to locate the arrays adjacently.
Consider:
int i[1];
int j[1];
int k[1];
By your logic, i+1==j and j+1==k are strictly conforming, but i+1==k is
not. But as far as everything in the language specification is concerned,
they're semantically identical. It makes no sense for their conformance
levels to be different -- either they're all strictly conforming or none
are. Where in the specification does it ever suggest that the memory
layout should be ijk rather than kji or ikj?
--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: markw65@my-dejanews.com
Date: 1998/11/14 Raw View
In article <72ia18$k2e$1@uuneo.neosoft.com>,
"Bill Wade" <bill.wade@stoner.com> wrote:
> I read that differently.
> >, though most real
> >implementations would (and will continue to) yield "truefalse". That
> >the standard departs from practice, here, seems a defect. That is,
> >the standard seems to require padding between a and b to ensure that
> >operator== will have correct results. Nobody pads, and the standard
> >should permit not padding.
> Nothing about the statement
> X iff A or B or C
> implies that it is illegal for both B and C to be true.
> X == "Two pointers of the same type compare equal"
> A == "they are both null"
> B == "both point to the same object"
> C == "both point one past the end of the same array"
> of course other parts of the standard say (!A || !B).
Except that its a *definition*. So B really reads "both are required to point
to the same object in all conforming implementations". So B & C _are_
mutually exclusive for unrelated objects.
Mark Williams
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/14 Raw View
markw65@my-dejanews.com wrote:
> In article <72ia18$k2e$1@uuneo.neosoft.com>,
> "Bill Wade" <bill.wade@stoner.com> wrote:
> > I read that differently.
> > >, though most real
> > >implementations would (and will continue to) yield "truefalse". That
> > >the standard departs from practice, here, seems a defect. That is,
> > >the standard seems to require padding between a and b to ensure that
> > >operator== will have correct results. Nobody pads, and the standard
> > >should permit not padding.
> > Nothing about the statement
>
> > X iff A or B or C
> > implies that it is illegal for both B and C to be true.
> > X == "Two pointers of the same type compare equal"
> > A == "they are both null"
> > B == "both point to the same object"
> > C == "both point one past the end of the same array"
> > of course other parts of the standard say (!A || !B).
> Except that its a *definition*. So B really reads "both are required to point
> to the same object in all conforming implementations". So B & C _are_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There's no such wording in the standard. Wording like that is contrary
to the general style of the standard. The standard sets requirements on
each implementation seperately. It doesn't set requirements on one
implementation that depend upon what is or is not possible on all
implementations.
> mutually exclusive for unrelated objects.
If that's true, it should be fixed, since it pointlessly requires
padding at the end of each object. That's why I doubt that was the
intent.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/16 Raw View
In article <mlF22.38$cf2.301656@brnws01.ne.mediaone.net>, Christopher M.
Gurnee <gurnec_at_mediaone_dot_net@127.0.0.1> writes
>This was (thankfully) changed in the IS. Two pointers of the same type
>compare equal *if and only if* they are both null, both point to the
>same object, or both point one past the end of the same array.
>Specifically, the following:
>
>char a[16];
>char b[16];
>
>cout << boolalpha << (a+16 == b) << (b + 16 == a);
>
>must print "truetrue" (assuming, of course, the locale library wasn't
>broken in this regard : )
I must be getting tired/old but I simply cannot see any way that your
source could print out truetrue. Any of:
truefalse (likely)
falsefalse(for some special implementation strategies for arrays)
falsetrue (unlikely but certainly possible)
truetrue NEVER
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/16 Raw View
In article <364DF9E3.C75300E4@wizard.net>, James Kuyper
<kuyper@wizard.net> writes
>If that's true, it should be fixed, since it pointlessly requires
>padding at the end of each object. That's why I doubt that was the
>intent.
At runtime how does your executable know what object a pointer is
pointing to? Simply because it finds an object at that address. There
is no way that you can detect from within your program whether a pointer
passed to a function was computed from the address of any object, all
you can observe is where it points.
int a[100];
int b;
If b is contiguous to a[99] then we can get its address as a+100 or as
&b. What the standard requires is that programmers not assume that
there will be any object found at a+100, but none the less they are
allowed to compare addresses with a+100 and if the unknown address
points to the same 'byte' as a+100 the expression will evaluate as true,
and if not (as long as your unknown address is actually within your
address space -- point at or into some object) it will return false. If
the unkown address violates my parenthesised cnstraint you have
undefined behaviour.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: zalman@netcom.com (Zalman Stern)
Date: 1998/11/16 Raw View
Bill Wade (bill.wade@stoner.com) wrote:
: union
: {
: char u[2];
: char v[3];
: } z;
: Are you suggesting that z.u+2 should compare unequal to &z.v[2]?
I believe the text of the Standard makes it clear that a union is a single
object so the example is a red herring in this context.
Nathan's point is that the text of the Standard will not be true in
practice. I.e. he was not suggesting that anything you know and love be
changed, but that the standard probably promises more than you will get
from real compilers and runtimes.
(Note also that even if the Standard did make this guarantee, its a bad
idea to depend on it because real programs often have user written
allocators of one sort or another that can easily break the guarantee. E.g.
In code that allocates a large array and then subdivides the array, it
would be a pain to have to insert "guard bytes" between the subobjects that
are returned. The whole large array is of course a single object for
Standard purposes. One must be aware that the term "object" is somewhat
overloaded. In this context, it does not mean an instance of a class.)
-Z-
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: markw65@my-dejanews.com
Date: 1998/11/16 Raw View
In article <364DF9E3.C75300E4@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
> markw65@my-dejanews.com wrote:
>
> > Except that its a *definition*. So B really reads "both are required to point
> > to the same object in all conforming implementations". So B & C _are_
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> There's no such wording in the standard. Wording like that is contrary
> to the general style of the standard. The standard sets requirements on
> each implementation seperately. It doesn't set requirements on one
> implementation that depend upon what is or is not possible on all
> implementations.
Of course the wording isnt there. It doesnt need to be. Its a definition.
>
> > mutually exclusive for unrelated objects.
>
> If that's true, it should be fixed, since it pointlessly requires
> padding at the end of each object. That's why I doubt that was the
> intent.
I also doubt that the intent was to require padding (although its not
required at the end of each object... only if the next object has the same
type). But mistakes are made. And the statement "a & b happen to point to the
same address in memory" (which is your interpretation of the definition)
makes a complete mockery of the "if and only if".
Mark Williams
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/11/16 Raw View
Barry Margolin wrote:
>
> In article <364c7a19.265612481@news.motu.com>,
> David Abrahams <abrahams@spam.motu.com> wrote:
> >I see why the standard *seems* to require padding between arrays, but
> >I'm not sure that it in fact does. Since I've heard this perception
> >before, I think a clarifying remark in teh standard may be in order.
> >
> >int i[1];
> >int j[1];
> >
> >On many implementations, i+1 == j.
> >
> >Now let's ask the question: is this strictly conforming?
> >I say yes:
> >i+1 and j are pointers of the same type, so we have to ask: do they
> >satisfy any of the requirements that are OR'd together above
> >a. they are both null (NO)
> >b. both point to the same object or function (YES: j[0])
> >c. both point one past the end of the same array (YES: i+1)
>
> The notion "point to the same object" should be taken in the context of the
> abstract machine. i+1 points to, or one past the end of, the object i, j
> points to, or one past the end of, the object j. Thus, you are not
> permitted to compare them.
You are permitted to compare any two pointers of the same type
(according to the quoted standard text). The question which is
discussed here is whether it may compare as "true" in the specific
situation.
>
> If the constraint on comparing pointers were dependent on physical layout,
> it would be nonsensical.
But the *result* of comparing a past-the-end pointer to a
pointer-to-object will be dependent on physical layout, in
about every existing implementation. The question is: Are
all the implementations non-conforming in this respect?
> "Strictly conforming" is supposed to be a quality
> of code that's independent of implementations. But by your reasoning, the
> expression is strictly conforming only because your implementation happens
> to locate the arrays adjacently.
Quite the other side round: "Strictly conforming" is supposed to
be a quality of implementations.
Author: abrahams@spam.motu.com (David Abrahams)
Date: 1998/11/16 Raw View
On 14 Nov 1998 00:37:27 GMT, Barry Margolin <barmar@bbnplanet.com>
wrote:
>
>In article <364c7a19.265612481@news.motu.com>,
>David Abrahams <abrahams@spam.motu.com> wrote:
>>I see why the standard *seems* to require padding between arrays, but
>>I'm not sure that it in fact does. Since I've heard this perception
>>before, I think a clarifying remark in teh standard may be in order.
>>
>>int i[1];
>>int j[1];
>>
>>On many implementations, i+1 == j.
>>
>>Now let's ask the question: is this strictly conforming?
>>I say yes:
>>i+1 and j are pointers of the same type, so we have to ask: do they
>>satisfy any of the requirements that are OR'd together above
>>a. they are both null (NO)
>>b. both point to the same object or function (YES: j[0])
>>c. both point one past the end of the same array (YES: i+1)
>
>The notion "point to the same object" should be taken in the context of the
>abstract machine. i+1 points to, or one past the end of, the object i, j
>points to, or one past the end of, the object j. Thus, you are not
>permitted to compare them.
>
>If the constraint on comparing pointers were dependent on physical layout,
>it would be nonsensical. "Strictly conforming" is supposed to be a quality
>of code that's independent of implementations. But by your reasoning, the
>expression is strictly conforming only because your implementation happens
>to locate the arrays adjacently.
Ugh, I'm sorry. I see now that my post unintentionally left a huge
misinterpretation trap, and Mr. Margolin just fell into it.
Actually, in my post "strictly conforming" refers to a property of the
C++ implementation, not of the code compiled with that implementation.
Of course Mr. Margolin will get no argument from me on his claim that
the code "i + 1 == j" isn't strictly portable (I think that's what he
means to say -- any implementation is allowed to accept that code, and
even to give it defined semantics).
My argument is that an implementation which allows that expression and
gives a result of true when evaluating it is strictly conforming: thus
no padding is required between arrays (see the rest of this thread)
-Dave
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: 1998/11/16 Raw View
In article <li+8koBymxT2Ewvu@robinton.demon.co.uk>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
> In article <364DF9E3.C75300E4@wizard.net>, James Kuyper
> <kuyper@wizard.net> writes
> >If that's true, it should be fixed, since it pointlessly requires
> >padding at the end of each object. That's why I doubt that was the
> >intent.
>
> At runtime how does your executable know what object a pointer is
> pointing to? Simply because it finds an object at that address. There
> is no way that you can detect from within your program whether a pointer
> passed to a function was computed from the address of any object, all
> you can observe is where it points.
>
> int a[100];
> int b;
>
> If b is contiguous to a[99] then we can get its address as a+100 or as
> &b. What the standard requires is that programmers not assume that
> there will be any object found at a+100, but none the less they are
> allowed to compare addresses with a+100 and if the unknown address
> points to the same 'byte' as a+100 the expression will evaluate as true,
> and if not (as long as your unknown address is actually within your
> address space -- point at or into some object) it will return false. If
> the unkown address violates my parenthesised cnstraint you have
> undefined behaviour.
I think the result of a long discussion in comp.std.c (and there is no
reason why this should be different in comp.std.c++) was that a pointer
pointing past the end of an object may - by pure coincidence - point to
some other object as well. A pointer can only point to one object,
therefore &a [99] can only point to a[99] and not to b. But &a [100]
doesnt point to "a" or any part of it, therefore it is allowed to point to
some other object.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/16 Raw View
Section 5.10 says: "Two pointers of the same type compare equal if and
only if they are both null, both point to the same object or function,
or both point one past the end of the same array."
Nathan pointed out that the last two options are not mutually exclusive.
For instance, on an implementation which allocates the following two
arrays contiguously:
int a[16], b[16];
a+16 and b both point to the same object: b[0]
a+16 and b both point one past the end of the same array: 'a'
Therefore, those two pointers must compare equal ON THAT IMPLEMENTATION,
even though they don't have to compare equal in general.
markw65@my-dejanews.com objected to that interpretation, saying:
...
> B == "both point to the same object"
...
> Except that its a *definition*. So B really reads "both are required to point
> to the same object in all conforming implementations".
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now, I don't see section 5.10 as being a definition, except of the
behavior required of the == and != operators. I don't see wording
corresponding to the section I've emphasized. I don't see how that
wording could be an inferred from the claim that 5.10 is a definition.
However, if we assume his interpretation is correct, then a+16 is
required to be != b. This either prohibits contiguous allocation of a
and b, or it requires that pointers contain extra information sufficient
to allow pointer comparisons to give a different result than a simple
address comparison would. I doubt that anybody intended to impose either
requirement.
Francis Glassborow wrote:
>
> In article <364DF9E3.C75300E4@wizard.net>, James Kuyper
> <kuyper@wizard.net> writes
> >If that's true, it should be fixed, since it pointlessly requires
> >padding at the end of each object. That's why I doubt that was the
> >intent.
>
> At runtime how does your executable know what object a pointer is
> pointing to? Simply because it finds an object at that address.
If markw's interpretation is correct, then any implementation that
allocates objects contiguously would have to include an indication of
the object pointed to as part of the pointer, and use that indicator
whenever comparing pointers for equality.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/11/16 Raw View
James Kuyper wrote:
>
> markw65@my-dejanews.com wrote:
[...]
> > > Nothing about the statement
> >
> > > X iff A or B or C
>
> > > implies that it is illegal for both B and C to be true.
> > > X == "Two pointers of the same type compare equal"
> > > A == "they are both null"
> > > B == "both point to the same object"
> > > C == "both point one past the end of the same array"
> > > of course other parts of the standard say (!A || !B).
>
> > Except that its a *definition*. So B really reads "both are required to point
> > to the same object in all conforming implementations". So B & C _are_
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> There's no such wording in the standard. Wording like that is contrary
> to the general style of the standard. The standard sets requirements on
> each implementation seperately. It doesn't set requirements on one
> implementation that depend upon what is or is not possible on all
> implementations.
>
> > mutually exclusive for unrelated objects.
>
> If that's true, it should be fixed, since it pointlessly requires
> padding at the end of each object. That's why I doubt that was the
> intent.
Indeed, I think if the standard really states that, the standard
is self-contradictory. Look at the following code:
typedef int intarray[10];
intarray i[20];
Now, i is an array of 20 intarray objects, of which each one is
an array of 10 ints. AFAIK the standard demands that
- sizeof(intarray) == 10*sizeof(int)
(so there's no "intrinsic" padding at the end of intarray)
- there's no padding between the different intarray objects in i.
Together, it follows that i[0]+10 == i[1]+0.
i[0]+10 is the one-past-end pointer of the array object i[0]
i[1]+0 is a pointer to the first object of the array object i[1]
So the standard *demands* in that case that a one-past-end pointer
compares equal to a pointer to existing object.
Unless I got something wrong, of course.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/16 Raw View
markw65@my-dejanews.com wrote:
>
> In article <364DF9E3.C75300E4@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
> >
> > markw65@my-dejanews.com wrote:
>
> >
> > > Except that its a *definition*. So B really reads "both are required to point
> > > to the same object in all conforming implementations". So B & C _are_
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >
> > There's no such wording in the standard. Wording like that is contrary
> > to the general style of the standard. The standard sets requirements on
> > each implementation seperately. It doesn't set requirements on one
> > implementation that depend upon what is or is not possible on all
> > implementations.
>
> Of course the wording isnt there. It doesnt need to be. Its a definition.
I'll agree that 5.10 is a definition of the proper behavior of the ==
and != operators. I don't see why the fact that it is a definition is
relevant. In particular, I don't see how you derived your wording from
that fact.
All conforming implementations must comply with 5.10; that's
unambiguously true. When those conditions are met, the pointers must
compare equal. When those conditions are not met, the pointers must
compare unequal. Whether those conditions are met depends (I claim, and
you disagree) upon the implementation. Therefore, whether the pointers
compare equal depends upon the implementation. The comparison yields
different results under different implementations - there's nothing
unusual about that.
...
> type). But mistakes are made. And the statement "a & b happen to point to the
> same address in memory" (which is your interpretation of the definition)
> makes a complete mockery of the "if and only if".
It doesn't make a mockery of it. It just limits the usefulness of
pointers one-past-the-end of an array. It doesn't prevent what is
already essentially their only useful purpose: testing a pointer derived
from one within the same array, to avoid incrementing the pointer any
farther.
Most importantly, it permits contiguous allocation of objects, and
allows implementation of pointer comparisons as simple address
comparisons, on appropriate architectures.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1998/11/16 Raw View
markw65@my-dejanews.com wrote in message
<72mto5$fij$1@nnrp1.dejanews.com>...
>I also doubt that the intent was to require padding (although its not
>required at the end of each object... only if the next object has the same
>type). But mistakes are made. And the statement "a & b happen to point to
the
>same address in memory" (which is your interpretation of the definition)
>makes a complete mockery of the "if and only if".
"if and only if" does not turn 'or' into 'xor'. What it does is prevent
extension of the set.
'if' identifies sufficient conditions.
A person is a parent if they have a son.
'only if' identifies necessary conditions.
A person is a mother only if they are a parent.
'if and only if' identify necessary and sufficient conditions.
A person is a parent if and only if they have a son or they have a daughter.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/16 Raw View
markw65@my-dejanews.com wrote:
>
> In article <364DF9E3.C75300E4@wizard.net>,
> James Kuyper <kuyper@wizard.net> wrote:
> >
> > markw65@my-dejanews.com wrote:
>
> >
> > > Except that its a *definition*. So B really reads "both are required to point
> > > to the same object in all conforming implementations". So B & C _are_
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >
> > There's no such wording in the standard. Wording like that is contrary
> > to the general style of the standard. The standard sets requirements on
> > each implementation seperately. It doesn't set requirements on one
> > implementation that depend upon what is or is not possible on all
> > implementations.
>
> Of course the wording isnt there. It doesnt need to be. Its a definition.
I don't understand your argument. Let's consider a simple, nonsense
case. Let's imagine that the standard was amended to require the
existence of a function
int small(size_t n);
and that the standard defines that small() "will return a non-zero value
if and only if n<sizeof(long). In this analogy, "n<sizeof(long)"
replaces "both point to the same object", and I'm simplifying by
removing the other two cases.
Your claim that "both are required to point to the same object in all
conforming implementations" would correspond in this analogy to
"n<sizeof(long) is required for all conforming implementations".
Therefore, the following implementation of small() wouldn't be allowed:
int small(size_t n){
return n<sizeof(long);
}
Instead, since on some implementations, sizeof(long) could be as small
as 1, your style of interpretation would imply that small() must be
implemented as:
int small(size_t n) {
return n<1;
}
Am I interpreting your logic correctly? Do you think that this is what
would be implied by such a definition of small()? If not, why do you
think section 5.10 should be interpreted differently?
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/11/16 Raw View
> In article <364c7a19.265612481@news.motu.com>,
> David Abrahams <abrahams@spam.motu.com> wrote:
> >int i[1];
> >int j[1];
> >
> >On many implementations, i+1 == j.
> >Now let's ask the question: is this strictly conforming?
> >I say yes:
In article <oP332.47$3I3.497296@burlma1-snr1.gtei.net>,
Barry Margolin <barmar@bbnplanet.com> wrote:
> The notion "point to the same object" should be taken in the context of the
> abstract machine. i+1 points to, or one past the end of, the object i, j
> points to, or one past the end of, the object j. Thus, you are not
> permitted to compare them.
>
> If the constraint on comparing pointers were dependent on physical layout,
> it would be nonsensical. "Strictly conforming" is supposed to be a quality
> of code that's independent of implementations. But by your reasoning, the
> expression is strictly conforming only because your implementation happens
> to locate the arrays adjacently.
>
> Consider:
>
> int i[1];
> int j[1];
> int k[1];
>
> By your logic, i+1==j and j+1==k are strictly conforming, but i+1==k is
> not. But as far as everything in the language specification is concerned,
> they're semantically identical. It makes no sense for their conformance
> levels to be different -- either they're all strictly conforming or none
> are. Where in the specification does it ever suggest that the memory
> layout should be ijk rather than kji or ikj?
Reminds me of part of a C test suite I saw many years ago. They
were trying to write portable code and at the same time they
were trying to determine if a subroutine used significantly more
storage than it's local variables. So they declared about 50
variables (or was it 50 arrays) that were identical types and
size, in alphabetical order. What I remember best was the
comments, which went something like this:
// There are 4 ways to arrange the order of local variables:
// 1: The order that they are declared
// 2: In order depending on size
// 3: Alphabetically
// 4: Something else
To check for case #4, they compared the address of the end of the
first variable to the address of the start of the second. If they
were not adjacent, then the subroutine concluded that we can't
determine how much memory the function used, and so it exited
without any errors. If they were adjacent, then the function could
go on and make other checks...
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: markw65@my-dejanews.com
Date: 1998/11/17 Raw View
In article <3650260F.80A11CA4@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
>
> Indeed, I think if the standard really states that, the standard
> is self-contradictory. Look at the following code:
>
> typedef int intarray[10];
>
> intarray i[20];
>
> Now, i is an array of 20 intarray objects, of which each one is
> an array of 10 ints. AFAIK the standard demands that
>
> - sizeof(intarray) == 10*sizeof(int)
> (so there's no "intrinsic" padding at the end of intarray)
> - there's no padding between the different intarray objects in i.
>
> Together, it follows that i[0]+10 == i[1]+0.
>
> i[0]+10 is the one-past-end pointer of the array object i[0]
> i[1]+0 is a pointer to the first object of the array object i[1]
>
> So the standard *demands* in that case that a one-past-end pointer
> compares equal to a pointer to existing object.
>
> Unless I got something wrong, of course.
Nothing wrong. i[0]+10 and i[1]+0 are required by the standard to refer to the
same object, and so they are also required by the standard to compare equal.
On the other hand, given
int i;
int j;
&i+1 and &j do not refer to the same object, and so may not compare equal.
Mark Williams
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/17 Raw View
In article <365050AF.41C6@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>If markw's interpretation is correct, then any implementation that
>allocates objects contiguously would have to include an indication of
>the object pointed to as part of the pointer, and use that indicator
>whenever comparing pointers for equality.
Sorry that does not work unless you require that all pointers store the
way they were calculated. Consider
int a[10]
int * p = a;
int i,j;
int * fn(int * ptr) { return ptr+12;}
int main() {
cout << ((&i == fn(a)) ? "true " : "false");
return 0;
}
How do you propose that an implementation detect that the return value
from fn() does not meet the constraints given? If you are going to
require that this program always output 'false' then every existing
implementation of C and C++ is broken and no one would want to use one
that wasn't.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: abrahams@spam.motu.com (David Abrahams)
Date: 1998/11/17 Raw View
On 17 Nov 98 13:01:21 GMT, markw65@my-dejanews.com wrote:
>On the other hand, given
>int i;
>int j;
>
>&i+1 and &j do not refer to the same object, and so may not compare equal.
Au contraire, nothing in the standard forbids &i+1 and &j from
referring to the same object, and so on any given implementation they
are allowed compare equal.
What's not allowed in this case? The user is not allowed to rely on
the results of such a comparison (unless of course the
implementation's documentation says otherwise).
I think you're confusing a restriction on users with a restriction on
implementations.
-Dave
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: markw65@my-dejanews.com
Date: 1998/11/17 Raw View
OK, in the face of overwhelming opposition (and the fact that I really dont
care... its clearly not the intent to require padding) I give in...
one-past-the-end _can_ be the same as some other object.
But I think I noticed another problem with that if and only if.
char *x = new char[10];
char *y = x;
delete [] x;
...
if (x == y) {
...
}
Now... on any implementation where x == y (ie almost all of them), we must
have (at least) one of: a) x and y are nul b) x and y point to the same
object c) x and y point one past the end of the same array
So if x != 0 and x == y we must have that either x or x-1 points to a valid
object. I wouldnt like to bet on it... :-)
In fact, given an arbitrary pointer:
if (x && x == x && x + 1 == x + 1) {
// it is safe to dereference x here :-)
}
Ok. What did I miss?
Mark Williams
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/17 Raw View
Francis Glassborow wrote:
>
> In article <365050AF.41C6@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >If markw's interpretation is correct, then any implementation that
> >allocates objects contiguously would have to include an indication of
> >the object pointed to as part of the pointer, and use that indicator
> >whenever comparing pointers for equality.
>
> Sorry that does not work unless you require that all pointers store the
> way they were calculated. Consider
You don't need to store the information about how they were calculated,
you merely need to carry out the calculations so as to retain the
information about the object they were derived from.
> int a[10]
> int * p = a;
> int i,j;
>
> int * fn(int * ptr) { return ptr+12;}
>
> int main() {
> cout << ((&i == fn(a)) ? "true " : "false");
> return 0;
> }
>
> How do you propose that an implementation detect that the return value
> from fn() does not meet the constraints given? ...
A pointer would have to be internally represented by the address of the
base object, and an offset from that base. New pointers created from
existing ones by any operation would copy the base, and modify the
offset. Pointers with different bases would compare un-equal.
Thus:
int *p=a;
Would create p as a pointer with base=&a, offset=0.
fn(a)
Would create a temporary pointer with base=&a, offset=0, accessed from
within fn() by the name ptr.
ptr+12
Would create a new temporary pointer with base=&a,
offset=12*sizeof(int). This temporary would be used as the return value
of fn().
&i
Would create a temporary pointer with base=&i, offset=0.
&i == fn(a)
Would compare those last two temporaries, notice they have different
bases, and return 0.
> ... If you are going to
> require that this program always output 'false' then every existing
> implementation of C and C++ is broken and no one would want to use one
> that wasn't.
I agree, which is why I hope that markw's interpretation is incorrect,
and why I want it changed if he's right.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/11/17 Raw View
Mark Williams <markw65@my-dejanews.com> wrote:
>> On the other hand, given
>> int i;
>> int j;
>>
>> &i+1 and &j do not refer to the same object, and so may not compare
>> equal.
David Abrahams wrote:
> Au contraire, nothing in the standard forbids &i+1 and &j from
> referring to the same object, and so on any given implementation they
> are allowed compare equal.
Mark obviously meant to say that the addresses "might not compare
equal." So you're both right.
-- David R. Tribble, dtribble@technologist.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ross Smith" <ross.s@ihug.co.nz>
Date: 1998/11/12 Raw View
Christopher M. Gurnee wrote in message ...
>Hans Olsson <"Email_To::.Hans.Olsson"@dna.lth.se> wrote in message
><72elv2$3jb$1@news.lth.se>...
>>
>>I see no problem with your statement if you mean comparison with 'operator<',
>>but I was discussing the template 'less' that at least in CD2 explicitly
>>is required to introduce a total order even if 'operator<' does not.
>
>I'm not sure where you're getting that definition. In both CD2 and the
>IS, less is defined as returning (arg1 < arg2). No additional
>guarantees are made.
Not true. CD2 section 20.3.3 [lib.comparisons]:
>8 For templates greater, less, greater_equal, and less_equal, the spe-
> cializations for any pointer type yield a total order, even if the
> built-in operators <, >, <=, >= do not.
Was this removed in the final standard? That would be a bad move.
--
Ross Smith ................................... mailto:ross.s@ihug.co.nz
.............. The Internet Group, Auckland, New Zealand ..............
* * * * *
"Screw up your courage. You've screwed up everything 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/11/13 Raw View
Christopher M. Gurnee<gurnec_at_mediaone_dot_net@127.0.0.1> wrote:
>Hans Olsson <"Email_To::.Hans.Olsson"@dna.lth.se> wrote
>>>> BTW, if less still is defined as total ordering for pointers: how
>>>> does this include pointers to end-plus-one of arrays?
>>>> (Which might be identical to the start of the next array).
>>... I was discussing the template 'less' that at least
>>in CD2 explicitly is required to introduce a total order even if
>>'operator<' does not.
>
>I'm not sure where you're getting that definition. In both CD2 and the
>IS, less is defined as returning (arg1 < arg2). No additional
>guarantees are made.
This is a false statement. In fact, at the end of [lib.comparisons]
we have:
For templates greater, less, greater_equal, and less_equal, the
specializations for any pointer type yield a total order, even if the
built-in operators <, >, <=, >= do not.
>>My main question was, however, if the final standard allows
>>comparison between pointers to e.g. different arrays with 'operator==',
>>and thus corrects the problems introduced in CD2.
>
>This was (thankfully) changed in the IS. Two pointers of the same type
>compare equal *if and only if* they are both null, both point to the
>same object, or both point one past the end of the same array.
>Specifically, the following:
>
>char a[16];
>char b[16];
>
>cout << boolalpha << (a+16 == b) << (b + 16 == a);
>
>must print "truetrue" ...
I don't know how you can get this conclusion from reading this
text. a+16 does *not* point to the "same object" as b, and
even if it were allowed to by some magic, b+16 could not
then point to the same object as a.
My reading is that the standard requires "falsefalse", though most real
implementations would (and will continue to) yield "truefalse". That
the standard departs from practice, here, seems a defect. That is,
the standard seems to require padding between a and b to ensure that
operator== will have correct results. Nobody pads, and the standard
should permit not padding.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/13 Raw View
In article <mlF22.38$cf2.301656@brnws01.ne.mediaone.net>,
Christopher M. Gurnee <gurnec_at_mediaone_dot_net@127.0.0.1> wrote:
>Hans Olsson <"Email_To::.Hans.Olsson"@dna.lth.se> wrote in message
><72elv2$3jb$1@news.lth.se>...
>>I see no problem with your statement if you mean comparison with
>'operator<',
>>but I was discussing the template 'less' that at least in CD2
>explicitly
>>is required to introduce a total order even if 'operator<' does not.
>
>I'm not sure where you're getting that definition. In both CD2 and the
>IS, less is defined as returning (arg1 < arg2). No additional
>guarantees are made.
20.3.3 (lib.comparison) in CD2:
...
8 For templates greater, less, greater_equal, and less_equal, the spe-
cializations for any pointer type yield a total order, even if the
built-in operators <, >, <=, >= do not.
>[Deleted] Two pointers of the same type
>compare equal *if and only if* they are both null, both point to the
>same object, or both point one past the end of the same array.
Good. I hoped so, but it's great to have it confirmed.
(Hmm... Isn't it a bit more complex?
How about one-past-end of one array and the start of the next one?)
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/13 Raw View
Christopher M. Gurnee wrote:
>
> Hans Olsson <"Email_To::.Hans.Olsson"@dna.lth.se> wrote in message
> <72elv2$3jb$1@news.lth.se>
...
> >I see no problem with your statement if you mean comparison with
> 'operator<',
> >but I was discussing the template 'less' that at least in CD2
> explicitly
> >is required to introduce a total order even if 'operator<' does not.
>
> I'm not sure where you're getting that definition. In both CD2 and the
> IS, less is defined as returning (arg1 < arg2). No additional
> guarantees are made.
Section 20.3.3, p8: "For templates greater, less, greater_equal, and
less_equal, the specializations for any pointer type yield a total
order, even if the built-in operators <, >, <=, >= do not.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/11/13 Raw View
> Hans Olsson <"Email_To::.Hans.Olsson"@dna.lth.se> wrote in message
> <72elv2$3jb$1@news.lth.se>...
> >My main question was, however, if the final standard allows
> >comparison between pointers to e.g. different arrays with 'operator==',
> >and thus corrects the problems introduced in CD2.
In article <mlF22.38$cf2.301656@brnws01.ne.mediaone.net>,
"Christopher M. Gurnee" <gurnec_at_mediaone_dot_net@127.0.0.1> wrote:
> This was (thankfully) changed in the IS. Two pointers of the same type
> compare equal *if and only if* they are both null, both point to the
> same object, or both point one past the end of the same array.
^^^^^^^^^^^^^^^^^
> Specifically, the following:
>
> char a[16];
> char b[16];
>
> cout << boolalpha << (a+16 == b) << (b + 16 == a);
>
> must print "truetrue" (assuming, of course, the locale library wasn't
> broken in this regard : )
I don't think so.
If this code is in a struct or class, i.e.
class X {
char a[16];
char b[16];
public:
void func() { cout << boolalpha << (a+16==b) << (b+16==a); }
}
int main() {
X x;
x->func();
}
then it should print "truefalse".
If the code is NOT in a class or struct, i.e.
int main() {
char a[16];
char b[16];
cout << boolalpha << (a+16 == b) << (b + 16 == a);
}
then it can print any of the four combinations: "falsefalse",
"falsetrue", "truefalse", "truetrue".
And, IMHO, the latter, which you assert is the only valid
response, is the LEAST likely. These are NOT pointers to
one-past-the-end of the same array; a+16 is one-past-the-end
of a, while b+16 is one-past-the-end of b. (How could you
arrange memory so that the array a[] was both before and
after array b[]? Maybe there's some strange computer out
there with 32-byte segments, such that x==(x+32) for all
char*x, but that computer wouldn't be very useful for C++
anyway...)
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Matt Austern <austern@sgi.com>
Date: 1998/11/13 Raw View
"Ross Smith" <ross.s@ihug.co.nz> writes:
> >8 For templates greater, less, greater_equal, and less_equal, the spe-
> > cializations for any pointer type yield a total order, even if the
> > built-in operators <, >, <=, >= do not.
>
> Was this removed in the final standard? That would be a bad move.
It's still there, but for pointer types only. For everything other
than pointers, less<T> differs from operator< only in syntax.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/11/13 Raw View
Hans Olsson<Email_To::.Hans.Olsson@dna.lth.se> wrote:
>>> if less still is defined as total ordering for pointers: how
>>> does this include pointers to end-plus-one of arrays?
>>> (Which might be identical to the start of the next array).
>
>I assumed that meant that pointer comparison between pointers to
>different arrays would be allowed and give a total order for 'less'
>(that's the only sensible explanation I could find for the extra
>requirement).
This is correct. Comparisons between pointers to malloc'd single
objects, or objects in different arrays, are permitted using less<>.
The standard seems to imply that less<> is obliged to distinguish an
off-the-end pointer from the adjacent object, and that is probably
a defect in the standard. In other words, it seems to require padding
after arrays, but no implementation does that or will do it.
You should expect that real implementations might not distinguish
an off-the-end pointer from a pointer to the first element in
some other (sub)object.
>Since placing pointers to objects in different arrays in a map requires
>a total order I hope that the standard also allows it.
>(I believe e.g. Meyers uses maps of pointers in 'More Effective C++').
>
>My main question was, however, if the final standard allows
>comparison between pointers to e.g. different arrays with 'operator==',
>and thus corrects the problems introduced in CD2.
Here is what it says:
-1- The == (equal to) and the != (not equal to) operators have the
same semantic restrictions, conversions, and result type as the
relational operators except for their lower precedence and truth-value
result. ... Pointers to objects or functions of the same type
(after pointer conversions) can be compared for equality. Two pointers
of the same type compare equal if and only if they are both null, both
point to the same object or function, or both point one past the end
of the same array.
Operator< et al. only apply to elements of the same object or array,
but the paragraph above appears to extend this for the case of operator==.
If I'm reading this right, it is also a defect in the standard. Expect
the result of comparing an off-the-end value to a pointer (in)to a
different object to be unspecified.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Christopher M. Gurnee" <gurnec_at_mediaone_dot_net@127.0.0.1>
Date: 1998/11/13 Raw View
Ross Smith wrote in message <72fe91$o33$1@newsource.ihug.co.nz>...
>Christopher M. Gurnee wrote in message ...
<clip>
>>I'm not sure where you're getting that definition. In both CD2 and
the
>>IS, less is defined as returning (arg1 < arg2). No additional
>>guarantees are made.
>
>Not true. CD2 section 20.3.3 [lib.comparisons]:
>
>>8 For templates greater, less, greater_equal, and less_equal, the
spe-
>> cializations for any pointer type yield a total order, even if
the
>> built-in operators <, >, <=, >= do not.
>
>Was this removed in the final standard? That would be a bad move.
Nope, I was wrong, it's still there. Thanks for the reference. So, one
*can* use pointers as keys in an associative container. I wonder if
there are any actual implementations that actually need to partially
specialize less, et. al., for pointer types....
-Chris Gurnee
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Holger Szillat" <szillat@informatik.uni-tuebingen.de>
Date: 1998/11/13 Raw View
Christopher M. Gurnee schrieb in Nachricht ...
snip
>The problem here is that, in general, (p1 < p2) is false if p1 and p2
>both point to the same object, but if they point to different objects,
>anything goes. In particular, transitivity is not guaranteed here.
>This is, IMO, a defect in the standard.
>
>Comments, anyone?
>
snap
Just a boring comment/question: May this guarantee be missing, because of
the Intel 16-bit platform ?? There, an address-representation written as
seg:ofs was *not* unique. Then the transitivity would not hold ?!
But on "modern" 32-bit platforms, the transitivity law would/should work,
doesn't it ??
Holger Szillat
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: saroj@bear.com
Date: 1998/11/13 Raw View
In article <72fubv$kme$1@shell7.ba.best.com>,
ncm@nospam.cantrip.org (Nathan Myers) wrote:
>
> Christopher M. Gurnee<gurnec_at_mediaone_dot_net@127.0.0.1> wrote:
> >This was (thankfully) changed in the IS. Two pointers of the same type
> >compare equal *if and only if* they are both null, both point to the
> >same object, or both point one past the end of the same array.
> >Specifically, the following:
> >
> >char a[16];
> >char b[16];
> >
> >cout << boolalpha << (a+16 == b) << (b + 16 == a);
> >
> >must print "truetrue" ...
>
> I don't know how you can get this conclusion from reading this
> text. a+16 does *not* point to the "same object" as b, and
> even if it were allowed to by some magic, b+16 could not
> then point to the same object as a.
>
> My reading is that the standard requires "falsefalse", though most real
> implementations would (and will continue to) yield "truefalse".
According to the C9x, the first comparison may or may not print
true (Standard does not require either result).
Two pointers compare equal if ..., 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.
Footnote: Two objects may be adjacent in memory because they are adjacent
elements of a larger array or adjacent members of a structure with no
padding between them or because the implementation chose to place them so,
even though are unrlated.
-- Saroj Mahapatra
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: abrahams@spam.motu.com (David Abrahams)
Date: 1998/11/13 Raw View
On 13 Nov 98 13:46:09 GMT, ncm@nospam.cantrip.org (Nathan Myers)
wrote:
>Hans Olsson<Email_To::.Hans.Olsson@dna.lth.se> wrote:
>>My main question was, however, if the final standard allows
>>comparison between pointers to e.g. different arrays with 'operator==',
>>and thus corrects the problems introduced in CD2.
>
>Here is what it says:
>
> -1- The == (equal to) and the != (not equal to) operators have the
> same semantic restrictions, conversions, and result type as the
> relational operators except for their lower precedence and truth-value
> result. ... Pointers to objects or functions of the same type
> (after pointer conversions) can be compared for equality. Two pointers
> of the same type compare equal if and only if they are both null, both
> point to the same object or function, or both point one past the end
> of the same array.
I see why the standard *seems* to require padding between arrays, but
I'm not sure that it in fact does. Since I've heard this perception
before, I think a clarifying remark in teh standard may be in order.
int i[1];
int j[1];
On many implementations, i+1 == j.
Now let's ask the question: is this strictly conforming?
I say yes:
i+1 and j are pointers of the same type, so we have to ask: do they
satisfy any of the requirements that are OR'd together above
a. they are both null (NO)
b. both point to the same object or function (YES: j[0])
c. both point one past the end of the same array (YES: i+1)
-Dave
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1998/11/13 Raw View
Nathan Myers wrote in message <72fubv$kme$1@shell7.ba.best.com>...
>
>Christopher M. Gurnee<gurnec_at_mediaone_dot_net@127.0.0.1> wrote:
>>This was (thankfully) changed in the IS. Two pointers of the same type
>>compare equal *if and only if* they are both null, both point to the
>>same object, or both point one past the end of the same array.
>>Specifically, the following:
>My reading is that the standard requires "falsefalse"
I read that differently.
>, though most real
>implementations would (and will continue to) yield "truefalse". That
>the standard departs from practice, here, seems a defect. That is,
>the standard seems to require padding between a and b to ensure that
>operator== will have correct results. Nobody pads, and the standard
>should permit not padding.
Nothing about the statement
X iff A or B or C
implies that it is illegal for both B and C to be true.
X == "Two pointers of the same type compare equal"
A == "they are both null"
B == "both point to the same object"
C == "both point one past the end of the same array"
of course other parts of the standard say (!A || !B).
Consider this movie review guideline:
A movie is GREAT if and only if it has great action scenes or great comedy
scenes.
This doesn't exclude the possibility that some movie has both great action
scenes AND great comedy scenes.
Certainly a pointer may point one past the end of an array AND at an object
at the same time.
union
{
char u[2];
char v[3];
} z;
Are you suggesting that z.u+2 should compare unequal to &z.v[2]?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/11/12 Raw View
In article <729g6v$6sp$1@news.lth.se>,
Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
> BTW, if less still is defined as total ordering for pointers: how does this
> include pointers to end-plus-one of arrays?
> (Which might be identical to the start of the next array).
Comparing two pointers, which point to elements of different
arrays, gives undefined results. This would include the
past-the-end pseudo-element.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/12 Raw View
In article <72corp$69r$1@nnrp1.dejanews.com>, <AllanW@my-dejanews.com> wrote:
>In article <729g6v$6sp$1@news.lth.se>,
> Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
>> BTW, if less still is defined as total ordering for pointers: how does this
>> include pointers to end-plus-one of arrays?
>> (Which might be identical to the start of the next array).
>
>Comparing two pointers, which point to elements of different
>arrays, gives undefined results. This would include the
>past-the-end pseudo-element.
I see no problem with your statement if you mean comparison with 'operator<',
but I was discussing the template 'less' that at least in CD2 explicitly
is required to introduce a total order even if 'operator<' does not.
I assumed that meant that pointer comparison between pointers to
different arrays would be allowed and give a total order for 'less' (that's
the only sensible explanation I could find for the extra requirement).
Since placing pointers to objects in different arrays in a map requires
a total order I hope that the standard also allows it.
(I believe e.g. Meyers uses maps of pointers in 'More Effective C++').
My main question was, however, if the final standard allows
comparison between pointers to e.g. different arrays with 'operator==',
and thus corrects the problems introduced in CD2.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Christopher M. Gurnee" <gurnec_at_mediaone_dot_net@127.0.0.1>
Date: 1998/11/12 Raw View
Hans Olsson <"Email_To::.Hans.Olsson"@dna.lth.se> wrote in message
<72elv2$3jb$1@news.lth.se>...
>In article <72corp$69r$1@nnrp1.dejanews.com>, <AllanW@my-dejanews.com>
wrote:
>>In article <729g6v$6sp$1@news.lth.se>,
>> Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
>>> BTW, if less still is defined as total ordering for pointers: how
does this
>>> include pointers to end-plus-one of arrays?
>>> (Which might be identical to the start of the next array).
>>
>>Comparing two pointers, which point to elements of different
>>arrays, gives undefined results. This would include the
>>past-the-end pseudo-element.
>
>I see no problem with your statement if you mean comparison with
'operator<',
>but I was discussing the template 'less' that at least in CD2
explicitly
>is required to introduce a total order even if 'operator<' does not.
I'm not sure where you're getting that definition. In both CD2 and the
IS, less is defined as returning (arg1 < arg2). No additional
guarantees are made.
>I assumed that meant that pointer comparison between pointers to
>different arrays would be allowed and give a total order for 'less'
(that's
>the only sensible explanation I could find for the extra requirement).
>
>Since placing pointers to objects in different arrays in a map requires
>a total order I hope that the standard also allows it.
>(I believe e.g. Meyers uses maps of pointers in 'More Effective C++').
Such a map would only be well defined if the pointers pointed to
elements of the same array (or one past, or all of the same object, with
no interveneing access-specifiers). The standard does not otherwise
guarantee a total ordering of pointers (even of the same type). : (
The problem here is that, in general, (p1 < p2) is false if p1 and p2
both point to the same object, but if they point to different objects,
anything goes. In particular, transitivity is not guaranteed here.
This is, IMO, a defect in the standard.
Comments, anyone?
>My main question was, however, if the final standard allows
>comparison between pointers to e.g. different arrays with 'operator==',
>and thus corrects the problems introduced in CD2.
This was (thankfully) changed in the IS. Two pointers of the same type
compare equal *if and only if* they are both null, both point to the
same object, or both point one past the end of the same array.
Specifically, the following:
char a[16];
char b[16];
cout << boolalpha << (a+16 == b) << (b + 16 == a);
must print "truetrue" (assuming, of course, the locale library wasn't
broken in this regard : )
-Chris Gurnee
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/10 Raw View
One sometimes sees (e.g. in old Guru of the Week) that the draft standard
did not guarantee that the common idiom if(this==&rhs) would work
(it used protect against self-assignment in operator==).
AFAIK this and other problems for == were introduced in CD2 when trying
to correct the previous version (previous version made the result
of == defined for most pointer comparisons).
I could find a discussion about this in 1997 in c.s.c++, and
a statement that the final standard would be better.
However, I couldn't find the results, and thus want to know if the
following are defined with the "normal" values for
pointers to objects (ignoring multiple inheritance, user-defined
comparison operators, etc):
* p1==0
* p1==p2
* (p1<p2) || (p1>p2)
Similarly with templates equal_to, less. Here CD2 guarantee
a total ordering for less, greater, etc., but does not guarantee
that equal_to is an equivalence relation (it was probably assumed
that == was an equivalence relation).
BTW, if less still is defined as total ordering for pointers: how does this
include pointers to end-plus-one of arrays?
(Which might be identical to the start of the next array).
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]