Topic: C/C++ object identity
Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1997/06/11 Raw View
Tom Payne <thp@cs.ucr.edu> wrote:
>In comp.std.c++ Pablo Halpern <phalpern@truffle.ma.ultranet.com> wrote:
>
>: There seems to be agreement that there are two circumstances where the
>: result of the comparison should remain *unspecified* (but not
>: *undefined*).
>
>: The first is if one of the pointers is one-past the end of an array and
>: the other pointer does not point into that array. In this case, the
>: implementation should be allowed to return true for the equality test,
>: even though, technically, the pointers do not point to the same object.
>
>I thought that the intent of the concern was the opposite, namely
>that, in cases where the implementation actually allocates another
>object of the same type just past the last member of an array, the
>implementation should be allowed to return false when comparing for
>equality a pointer to that object and a pointer to "one past the end
>of the of the array," even though the two pointers in fact point to
>the same object.
Exactly. The implementation should be allowed to return either true or
false in this case (depending on whether the pointer representation
allows the two pointers to be distinguished), hence "unspecified"
behavior. My point was that even if the standard were clarified to
remove most of the "unspecified" equality tests (which I think it should
be), this situation should still be unspecified.
-------------------------------------------------------------
Pablo Halpern phalpern@truffle.ultranet.com
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.crud.com>
Date: 1997/06/11 Raw View
Herb Sutter wrote:
>
> "Paul D. DeRocco" <pderocco@ix.netcom.crud.com> wrote:
> >I think the standard should be reworded to say that string literals are
> >allowed to be constructed from overlapping objects.
>
> It already does. :-) It is unspecified whether or not string literals are
> stored in overlapping memory (covered in GotW #9).
No, what I meant was that the standard should be worded as above, in
which _objects_ are allowed to overlap, so that it wouldn't be necessary
to say that two distinct strings were allowed to be part of the _same_
object. It's a subtle bit of minutiae, intended to simplify the
definition of when operator== on two apparently different things is
allowed to return true.
--
Ciao,
Paul
(Please remove the extra "crud" from the return address,
which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: ok@cs.rmit.edu.au (Richard A. O'Keefe)
Date: 1997/06/05 Raw View
antispam.icedancer@antispam.ibm.net (Ken Walter) writes:
>In message <338DBD25.41C6@maths.nott.ac.uk> - "Dr A. N. Walker"
>> If the assignment to "p" isn't illegal [and I bow to Clive's
>> superior knowledge of the C?++ standard], then it darn well ought to
>> be! It's 22 years since Algol forbade assignments to pointers of
1997-22 = 1975 ^^^^^ clearly Algol 68
>> wider scope than the object pointed at, thereby preventing a whole
>> slew of really obscure program bugs.
>But Algol had to carry around the stack frame pointer with any pointer
>to check
False.
>and Algol didn't have dynamically allocated data (new/delete)
False.
>which could go away at any time.
loc ref real x = heap real;
involves dynamically allocated data.
--
Four policemen playing jazz on an up escalator in the railway station.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1997/06/06 Raw View
Julian Pardoe <pardoej@lonnds.ml.com> wrote:
>I believe it was the intention of the Standard that == and != be defined
>in all cases where valid pointers ae compared. The restrictions about
>pointing to the same object were supposed to reply to <, <= etc. If close
>reading of the Standard does not justify this interoretation then the wording
>of the Standard must be amended.
There seems to be agreement that there are two circumstances where the
result of the comparison should remain *unspecified* (but not
*undefined*).
The first is if one of the pointers is one-past the end of an array and
the other pointer does not point into that array. In this case, the
implementation should be allowed to return true for the equality test,
even though, technically, the pointers do not point to the same object.
The second is if both pointers point into string literals. In that case,
the results will depend one whether the implementation overlapped the
particular string literals in memory. However, if strcmp() returns
non-zero, then the pointers should never compare equal.
-------------------------------------------------------------
Pablo Halpern phalpern@truffle.ultranet.com
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: dak <pierreba@cae.ca>
Date: 1997/06/06 Raw View
Tom Payne <thp@cs.ucr.edu> wrote:
> James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
>
> : The only real problem that I see is that it never guarantees that two
> : pointers to different objects compare unequal.
>
> The editorial omission seems minor. Per 6.3.9: "If two pointers to
> object or incomplete types compare equal, they both are null pointers,
> or both point to the same object [whatever that means], or both point
> one past the last element of the same array object." Presumably, this
> should have been bi-conditional (i.e., "If and only if ... .") so
> that, when both pointers aren't null and don't point to the same
> object and don't point one past the last element of the same array,
> then they don't compare equal, i.e., they compare unequal. (They must
> return some result by #1 above, and that result is either zero or
> non-zero.)
>
> My problem, however, is with the concept of "same object," which seems
> to involve sameness of addresses, i.e., equality of pointers. Does
> this ill-founded circularity bother others? It's no doubt possible,
> though tedious, to replace it with a recursive definition, i.e.,
> well-founded circularity.
I think the problem is a language one. It lies in the fact that the action
of pointing is not defined in the standard. I think there should be an
addition to the glossary, or elsewhere, which would defines what "point to"
means. I do not remember who, but someone suggested to define "point to"
to mean "point to the byte which is", with byte defined as the smallest
addressable unit.
That way, the quoted paragraph would become: "If two pointers to object or
incomplete types compare equal, they both are null pointers, or both point
to (the byte which is) the same object, or both point (to the byte which is)
one past the last element of the same array object."
That would take care of the problem of putting spacing between array
variables. And since all implementations I know of do not put spacing then
I believe it would spell-out the intention of the standard.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1997/06/06 Raw View
"Clive D.W. Feather" <clive@on-the-train.demon.co.uk> wrote:
>Here's another example:
>
> int f (char *p, char *q)
> {
> /* Placeholder for anything that compares pointers */
> return p == q;
> }
>
> int main (int argc, char *argv [])
> {
> char c [5][5];
[ abbreviated ]
> /* The nub of the matter */
> return f (c [i], c [j] + k);
> }
>
>Consider the following inputs: [ for i, j, and k ]
>
> 2 2 0
> 2 1 5
>
> 2 3 0
> 2 2 5
>
>Explain why the second of each pair should be undefined if the first
>isn't (hint, f can't tell the difference).
c[i] and c[j] + k are pointers into the same object. Therefore, the DWP
states that they can compare equal.
The problem, as I see it, is that the pointers are never *required* to
compare equal. They *are* required to compare unequal under certain
(insufficient) circumstances. I believe an implementation can be
conforming if p == q was always false and p != q was always true.
The reason, I believe, for this sorry state of affairs is to prevent the
need for expensive checks in segmented architectures, where two pointers
to the same object may have different bit patterns. I believe that the
allowance goes to far, but that creating reasonable rules could require
a lot of work. For example, start with this rule:
If x and y are pointers of type T, then x == y if and only if x and y
are the same object. x != y is true if and only if x and y are not the
same object.
Now we need to make exceptions in the case that one of x or y is a
pointer past the end of an array. Also we need rules if x and/or y is a
null pointer.
Fine. Now, what about those architectures (like the x86) where x and y
could point to the same object but have different bit-patterns? Do we
force the compiler to look-up the physical addresses and compare them? I
think this lookup could be eliminated in most practical cases because
certain transformations on pointers were outside of the standard. If an
operating-system call returns two different pointers to the same memory,
that is outside of the standard and all bets are off. I, on the other
hand, the programmer uses "normal" operations like +, -, =, ++, --, etc.
to create one pointer from another, then I think it is reasonable to
require the implentation to ensure that the above rules continue to
hold. Indeed, I believe most x86 compilers currently do this (with the
possible exception of the huge memory model).
OK, so lets define the set of "normal" operations that keep pointers in
line. What about * and &. Is the expression "p == &*p" required to
evaluate true? Although I would answer "yes," this may start imposing
some overhead on some compilers. Even worse, should
"p == dynamic_cast<derived*>(static_cast<base*>(p))" always evaluate
true, even in the presence of virtual inheritence? The latter requires
that dynamic_cast always return the same bit-pattern as other methods of
computing p. Again, I think this is doable, but I haven't tried writing
a compiler lately.
In the mean time, there is a lot of code that looks like this:
X& X::operator=(const X& rhs)
{
if (&rhs != this)
{
// do assignment
}
return *this;
}
I'd hate for the standard to invalidate such code, expecially if it
doesn't provide an alternative test for identity.
-------------------------------------------------------------
Pablo Halpern phalpern@truffle.ultranet.com
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Dolf Grunbauer <dgrunbauer@baan.nl>
Date: 1997/06/06 Raw View
Richard A. O'Keefe wrote:
>
> antispam.icedancer@antispam.ibm.net (Ken Walter) writes:
> >In message <338DBD25.41C6@maths.nott.ac.uk> - "Dr A. N. Walker"
> >> If the assignment to "p" isn't illegal [and I bow to Clive's
> >> superior knowledge of the C?++ standard], then it darn well ought to
> >> be! It's 22 years since Algol forbade assignments to pointers of
> 1997-22 = 1975 ^^^^^ clearly Algol 68
>
> >> wider scope than the object pointed at, thereby preventing a whole
> >> slew of really obscure program bugs.
>
> >But Algol had to carry around the stack frame pointer with any pointer
> >to check
>
> False.
>
> >and Algol didn't have dynamically allocated data (new/delete)
>
> False.
>
> >which could go away at any time.
>
> loc ref real x = heap real;
>
> involves dynamically allocated data.
I even want to add that Algol 60 had the nice feature that in a function
(which was called a PROCEDURE I think) you could very easily allocate a
dynamic array like:
PROCEDURE function(n); int n;
BEGIN
int array(n);
...
END
My syntax may be way off, but you get the picture: based on an argument
you could put an array on stack. I always wondered why this feature is
not in C/C++.
Regards,
Dolf (dgrunbauer@baan.nl)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/06/06 Raw View
Dolf Grunbauer <dgrunbauer@baan.nl> writes:
>I even want to add that Algol 60 had the nice feature that in a function
>(which was called a PROCEDURE I think) you could very easily allocate a
>dynamic array like:
>
>PROCEDURE function(n); int n;
>BEGIN
> int array(n);
> ...
>END
>
>My syntax may be way off, but you get the picture: based on an argument
>you could put an array on stack. I always wondered why this feature is
>not in C/C++.
This feature has been proposed for C9X, the next revision of the C standard.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Steve Clamage <stephen.clamage@eng.sun.com>
Date: 1997/06/07 Raw View
Pablo Halpern wrote:
>
> The problem, as I see it, is that the pointers are never *required* to
> compare equal.
Huh? Pointers of the same type that point to the same object are
required to compare equal. Equality is also required in some other
cases.
Refer to the ISO C Standard 6.3.8 and 6.3.9,
and the C++ draft standard 5.9 and 5.10.
> The reason, I believe, for this sorry state of affairs is to prevent the
> need for expensive checks in segmented architectures, where two pointers
> to the same object may have different bit patterns.
Not so. If an implementation allows different bit patterns to
refer to the same address, it must still conform to all the pointer
comparison requirements. However the implementation chooses to get
the effect, the result of such comparisons must be "equal".
--
Steve Clamage, stephen.clamage@eng.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: ruchrist@online.no (Rune Christensen)
Date: 1997/06/07 Raw View
Dolf Grunbauer <dgrunbauer@baan.nl> wrote:
>
>PROCEDURE function(n); int n;
>BEGIN
> int array(n);
> ...
>END
>
>My syntax may be way off, but you get the picture: based on an argument
>you could put an array on stack. I always wondered why this feature is
>not in C/C++.
It is, althoug a little roundabout:
void *_alloca( size_t size );
E.g.
void function( int n )
{
int *array= static_cast<int*>( _alloca( n*sizeof(int ) );
...
}
Regards,
Rune Christensen
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Bradd W. Szonye" <bradds@concentric.net>
Date: 1997/06/07 Raw View
dak <pierreba@cae.ca> wrote in article
<Pine.A32.3.91.970605085903.17090A-100000@zorglub.cae.ca>...
>
>I think the problem is a language one. It lies in the fact that the action
>of pointing is not defined in the standard. I think there should be an
>addition to the glossary, or elsewhere, which would defines what "point to"
>means. I do not remember who, but someone suggested to define "point to"
>to mean "point to the byte which is", with byte defined as the smallest
>addressable unit.
>
>That way, the quoted paragraph would become: "If two pointers to object or
>incomplete types compare equal, they both are null pointers, or both point
>to (the byte which is) the same object, or both point (to the byte which is)
>one past the last element of the same array object."
>
>That would take care of the problem of putting spacing between array
>variables. And since all implementations I know of do not put spacing then
>I believe it would spell-out the intention of the standard.
Don't forget to first adjust the types of objects related by inheritance to
the same (suitable) type. When D is derived from B, a pointer to D and to B
can point to different bytes but the same object. When both pointers are
unambiguously converted to B* for comparison, they then point to the same
byte.
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~Bradds
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Peter Shenkin <shenkin@still3.chem.columbia.edu>
Date: 1997/06/07 Raw View
Fergus Henderson wrote:
>
> Dolf Grunbauer <dgrunbauer@baan.nl> writes:
>
> >I even want to add that Algol 60 had the nice feature that in a function
> >(which was called a PROCEDURE I think) you could very easily allocate a
> >dynamic array like:
> >
> >PROCEDURE function(n); int n;
> >BEGIN
> > int array(n);
> > ...
> >END
> >
> >My syntax may be way off, but you get the picture: based on an argument
> >you could put an array on stack. I always wondered why this feature is
> >not in C/C++.
>
> This feature has been proposed for C9X, the next revision of the C standard.
It's in Fortran90, by the way. It's nice to see that there are
several areas in which C is now trying to catch up with Fortran. :-)
-P.
--
**** "Deep Blue can't triumph in the game of life." (NY Times, 5/13/97) ***
* Peter S. Shenkin; Chemistry, Columbia U.; 3000 Broadway, Mail Code 3153 *
** NY, NY 10027; shenkin@columbia.edu; (212)854-5143; FAX: 678-9039 ***
*MacroModel WWW page: http://www.columbia.edu/cu/chemistry/mmod/mmod.html *
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/06/07 Raw View
ruchrist@online.no (Rune Christensen) writes:
>>I always wondered why this feature is not in C/C++.
>
>It is, althoug a little roundabout:
>
>void *_alloca( size_t size );
alloca() is not standard. It is not a part of ANSI/ISO C, and it is not
a part of draft proposed ISO C++.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1997/06/07 Raw View
Rune Christensen <ruchrist@online.no> wrote:
: Dolf Grunbauer <dgrunbauer@baan.nl> wrote:
: >
: >PROCEDURE function(n); int n;
: >BEGIN
: > int array(n);
: > ...
: >END
: >
: >My syntax may be way off, but you get the picture: based on an argument
: >you could put an array on stack. I always wondered why this feature is
: >not in C/C++.
: It is, althoug a little roundabout:
: void *_alloca( size_t size );
_alloca() is not a part of ANSI C. Neither is alloca(). Besides,
calling alloca() incurs performance penalty, while all the space for
all auto variables is allocated in one large swoop.
Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.crud.com>
Date: 1997/06/07 Raw View
Pablo Halpern wrote:
> There seems to be agreement that there are two circumstances where the
> result of the comparison should remain *unspecified* (but not
> *undefined*).
>
> The first is if one of the pointers is one-past the end of an array and
> the other pointer does not point into that array. In this case, the
> implementation should be allowed to return true for the equality test,
> even though, technically, the pointers do not point to the same object.
I'll reiterate that technically the pointer past the end of the array
doesn't point to an object at all.
> The second is if both pointers point into string literals. In that case,
> the results will depend one whether the implementation overlapped the
> particular string literals in memory. However, if strcmp() returns
> non-zero, then the pointers should never compare equal.
I think the standard should be reworded to say that string literals are
allowed to be constructed from overlapping objects. Then if "xyz"+2=="z"
is true, it's because the two pointers actually point to the same
object, and no special cases need to be introduced into the definition
of ==.
--
Ciao,
Paul
(Please remove the extra "crud" from the return address,
which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Clive D.W. Feather" <clive@on-the-train.demon.co.uk>
Date: 1997/06/09 Raw View
[Moderator's note: this thread has strayed off topic for comp.std.c++;
followups redirected to comp.std.c only. -fjh]
In article <5n64e2$557$1@goanna.cs.rmit.edu.au>, "Richard A. O'Keefe"
<ok@cs.rmit.edu.au> writes
>>and Algol didn't have dynamically allocated data (new/delete)
>False.
>>which could go away at any time.
> loc ref real x = heap real;
>involves dynamically allocated data.
but there is no way to make it "go away at any time" - it only goes away
when there are no valid pointers to it (which isn't necessarily even
when the variable x goes away).
begin
ref real z;
begin
ref real y;
begin
loc ref real x = heap real;
y = x;
end
z = y;
# The dynamic object is still accessible #
end
# The dynamic object is *still* accessible #
end
# *NOW* the dynamic object goes away. #
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <clive@davros.org>
Fax: +44 181 371 1037 | <clive@demon.net> | Abuse:
Written on my laptop; please observe the Reply-To address | <clive@bofh.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: herbs@cntc.com (Herb Sutter)
Date: 1997/06/09 Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.crud.com> wrote:
>I think the standard should be reworded to say that string literals are
>allowed to be constructed from overlapping objects.
It already does. :-) It is unspecified whether or not string literals are
stored in overlapping memory (covered in GotW #9).
[Disclaimer: The original article was cross-posted to comp.std.c, so Paul may
have meant C rather than C++... I don't know what the C standard says.]
---
Herb Sutter (mailto:herbs@cntc.com)
Current Network Technologies Corp. (http://www.cntc.com)
2695 North Sheridan Way, Suite 150, Mississauga ON Canada L5K 2N6
Tel 416-805-9088 Fax 905-822-3824
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/06/09 Raw View
"Clive D.W. Feather" <clive@on-the-train.demon.co.uk> writes:
|> Here's another example:
|>
|> int f (char *p, char *q)
|> {
|> /* Placeholder for anything that compares pointers */
|> return p == q;
|> }
|>
|> int main (int argc, char *argv [])
|> {
|> char c [5][5];
|> int i = 0, j = 0, k = 0;
|>
|> /* Placeholder for getting arbitrary valid values for i, j, k */
|> if (argc > 1) i = atoi (argv [1]) % 6;
|> if (argc > 2) j = atoi (argv [2]) % 6;
|> if (argc > 3) k = atoi (argv [3]) % 6;
|> assert (i >= 0 && j >= 0 && k >= 0);
|>
|> /* The nub of the matter */
|> return f (c [i], c [j] + k);
|> }
|>
|> Consider the following inputs:
|>
|> 2 2 0
|> 2 1 5
|>
|> 2 3 0
|> 2 2 5
|>
|> Explain why the second of each pair should be undefined if the first
|> isn't (hint, f can't tell the difference).
An implementation is allowed to use bounded pointers, in which case, f
probably can tell the difference. Dereferencing the second pointer is
undefined behavior in the second case of each pair, and the
implementation is allowed to carry this information with the pointer,
and (why not) use it in the comparison.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: msb@sq.com (Mark Brader)
Date: 1997/06/09 Raw View
Paul DeRocco:
| I think the standard should be reworded to say that string literals are
| allowed to be constructed from overlapping objects.
Already done, if we're talking about the C standard, as part of Technical
Corrigendum 2. The actual change, made in response to Defect Report 080, is:
# In subclause 6.1.4, page 31, change the last paragraph of Semantics
# (before the Example) from:
#
# < Identical string literals of either form need not be distinct.
# < If the program attempts to modify a string literal of either form,
# < the behavior is undefined.
#
# to:
#
# > These arrays need not be distinct provided their elements
# > have the appropriate values. If the program attempts to modify
# > such an array, the behavior is undefined.
--
Mark Brader | "The world little knows or cares the storm through
msb@sq.com | which you have had to pass. It asks only if you
SoftQuad Inc., Toronto | brought the ship safely to port." --Joseph Conrad
My text in this article is in the public domain.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1997/06/09 Raw View
Steve Clamage <stephen.clamage@eng.sun.com> wrote:
>Pablo Halpern wrote:
>>
>> The problem, as I see it, is that the pointers are never *required* to
>> compare equal.
>
>Huh? Pointers of the same type that point to the same object are
>required to compare equal. Equality is also required in some other
>cases.
>
>Refer to the ISO C Standard 6.3.8 and 6.3.9,
>and the C++ draft standard 5.9 and 5.10.
I'm sorry. I am getting confused. (I try not to post opinions based on
incomplete understanding, but I guess this one slipped by.)
Let's try to unravel the confusion. The following was quoted from the C
standard (not the C++ draft. I forget that this message was cross
posted.)
| 6.3.9 Equality Operators
| ...
| [5] ... If two pointers to object or incomplete types compare
| equal, they both are null pointers, or both point to the same object,
| or both point one past the last element of the same array object.
This says when two pointers cannot compare true: They cannot compare
true if all of the above conditions are false. I don't have a copy of
the C standard handy (I lost it the last time I moved), so I can't read
the rest of the context for this section. The above paragraph alone does
not say that two pointers are ever *required* to compare equal, only
that if they *do* compare equal, then one of the above conditions must
hold. (The statement "if the program crashes, it has a bug" does not
imply "If the program doesn't crash, it is bug-free.") Perhaps this is
just an editorial error and the above should read "If and only if two
pointers ..."
Now, I *do* have a copy of the C++ CD2. Section 5.9 gives the rules for
relational operators, saying that:
"-- If two pointers p and q of the same type point to different objects
that are not members of the same object or elements of the same array or
to different functions, or if only one of them is null, the results of
p<q,p>q,p<=q, and p>=q are unspecified"
Let me call the above portion of Section 5.9 "the Different Object
Rule." Then Section 5.10 says
"The == (equal to) and the != (not equal to) operators have the smae
semantic restrictions, conversions and result type as the relational
operators except for their lower precedence and truth-value result"
First point of confusion: Section 5.10 says that the same restrictions
as the relational operators. However, the Different Object Rule from
Section 5.9 mentiones each of the four relational operators *by name*
whereas most of section 5.9 refers to them as a group. Question: does
the Different Object Rule apply to operators == and !=. If so, then we
have a problem because the result of comparing pointers to different
objects for equality becomes unspecified.
Second point of confusion: Section 5.10 does not say when pointers must
compare equal or not equal. Do the semantics of Section 5.9 apply? If
so, then we have a problem whether or not the Different Object Rule
applies. If the Different Object Rule does not apply, then last
paragraph of Section 5.9 applies which says "-- Other pointer
comparisons are unspecified." This is equally unsatisfactory.
Third point of confusion (this is the one that did me in): Are the rules
for determining if two pointers compare equal inherited from C? If so,
what is the rule that says "If two pointers ... compare *unequal*
then..." In other words when *must* two pointers compare equal, when
*musn't* they compare equal, and when is it unspecified. As I
mentioned, from the out-of-context quote above, I can only determine
when they must *not* compare equal. I must say, the wording seems
obfuscatory to me. I would rather see "They compare equal if..." then
"If they compare equal then..." Both are straight-forward logical
constructions, but it is easier for my brain to get around the former.
That's my long-winded confusion. As far as I can tell, most people
contributing to this thread assume the interpretation, as Steve Clamage
wrote, that pointers to the same object must compare equal. Good. The
crux of the thread seems to be:
- If neither pointer points past the end of an array and they don't
point into the same object, the standard seems to leave the results
unspecified. The consensus seems to be that in this case, the result
should be false.
- If one of the pointers points past the end of an array and the other
does not point into the same array, then the standard again leaves the
result unspecified. Most people seem to think that this is OK (because
the address of an object past the end of an array may or may not be the
same as the address of an unrelated object), but it is more
controversial than the first.
Do I have it right, now?
-------------------------------------------------------------
Pablo Halpern phalpern@truffle.ultranet.com
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Tom Payne <thp@cs.ucr.edu>
Date: 1997/06/10 Raw View
In comp.std.c++ Pablo Halpern <phalpern@truffle.ma.ultranet.com> wrote:
: There seems to be agreement that there are two circumstances where the
: result of the comparison should remain *unspecified* (but not
: *undefined*).
: The first is if one of the pointers is one-past the end of an array and
: the other pointer does not point into that array. In this case, the
: implementation should be allowed to return true for the equality test,
: even though, technically, the pointers do not point to the same object.
I thought that the intent of the concern was the opposite, namely
that, in cases where the implementation actually allocates another
object of the same type just past the last member of an array, the
implementation should be allowed to return false when comparing for
equality a pointer to that object and a pointer to "one past the end
of the of the array," even though the two pointers in fact point to
the same object. Perhaps, I'm quibbling about the concept of "same
object," but presumably objects are the "same" if they have the same
address and type (aside from some address anomalies induced by
multiple inheritance).
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Tom Payne <thp@cs.ucr.edu>
Date: 1997/06/11 Raw View
In comp.std.c++ Pablo Halpern <phalpern@truffle.ma.ultranet.com> wrote:
[...]
: Let's try to unravel the confusion. The following was quoted from the C
: standard (not the C++ draft. I forget that this message was cross
: posted.)
: | 6.3.9 Equality Operators
: | ...
: | [5] ... If two pointers to object or incomplete types compare
: | equal, they both are null pointers, or both point to the same object,
: | or both point one past the last element of the same array object.
: This says when two pointers cannot compare true: They cannot compare
: true if all of the above conditions are false. I don't have a copy of
: the C standard handy (I lost it the last time I moved), so I can't read
: the rest of the context for this section. The above paragraph alone does
: not say that two pointers are ever *required* to compare equal, only
: that if they *do* compare equal, then one of the above conditions must
: hold. (The statement "if the program crashes, it has a bug" does not
: imply "If the program doesn't crash, it is bug-free.") Perhaps this is
: just an editorial error and the above should read "If and only if two
: pointers ..."
I agree that for readabiliy 6.3.9 should read "If and only if ..."
It does, however, say that:
Where the operands have types and values suitable for the
relational operators [ <, >, <=, and >= ], the semantics
detailed in 6.3.8 apply.
And 6.3.8 says that:
If two pointers to object or incomplete types both point to the
same object or both point one past the last element of the same
array object, they compare equal.
In particular, if they point to the same object, they MUST compare
equal. (The standard treats nonarray objects as "a pointer to the
first element of an array of length one ...")
The problem arises from the "suitability" requirement of the quoted
passage of 6.3.9, for 6.3.8 stipulates that:
If the objects pointed to are not members of the same aggregate
or union object, the result is undefined, with the following
exception [that you can compare any element of an array element
to its one-past-last element].
This passage of 6.3.8 applies specifically to relational comparisions,
but it indicates that pointers to unrelated objects are not "suitable
for the relational operators."
Some argue, therefore, that the standard leaves the result of such a
comparison undefined. I disagree, since pointers to unrelated objects
(of compatible types) meet the "Constraints" clause of 6.3.9:
One of the following shall hold ... [or] both operands are
pointers to qualified or unqualified version of compatible
types [or] ...
which implies (to me) that the result of such a comparison is defined.
They must, of course, compare unequal, since the clause you quoted
above prohibits pointers to unrelated objects from comparing equal.
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Clive D.W. Feather" <clive@on-the-train.demon.co.uk>
Date: 1997/05/29 Raw View
In article <5me5gu$358$1@miranda.gmrc.gecm.com>, Chris Dearlove
<chris.dearlove@gecm.com> writes
>:>the following comparisons are also possible
>:>(d) Pointer past end of array with object not in array
>:>(e) Pointer past end of array with another non-equal such pointer
>: These are also well defined.
>:>My question is would it matter if the results of (d) and (e) were
>:>explicitly undefined?
>: The whole point of the one-past-the-end rule is to allow the end of an
>: array *not* to be a special case.
The point is that *any* two valid pointers can be compared for equality.
>Whilst not doubting you at all it would be good to see an example,
>ideally of a case where extra otherwise unnecessary contortions are
>needed to avoid making a type (d) or type (e) comparison (I suspect an
>example for (e) is easier, so one with (d) would be better to nail
>the point).
What about:
int pointer_within (char *x, char *low, char *high)
{
char *p;
for (p = low; p <= high; p++)
if (x == p)
return 1;
return 0;
}
int main (void)
{
char s [1], t [10];
return pointer_within (s, t, t + sizeof (t)) +
pointer_within (t + 5, t + 2, t + 8);
}
>and the question about ... code, because a "natural" implementation
>which took no special action might or might not execulte the code.
>From this I went to the thought that (in code with any pretentions
>to portability, conformance etc.) such a comparison was a Bad Thing
Yes, because it is unspecified whether or not they are equal.
>and to the question could/should it be undefined.
No, because the pointers may have come via some intermediate variable;
you can't know whether they are into an array or to one-past-the-end.
>The problem with your answer is that beyond the end of
>an array is special in some cases (trying to look at the object)
>so it is not completely unreasonable to suppose it might be different
>here (though this does not involve looking at the object it does
>appear to be attempting to find out something it has no business
>knowing about).
The Standard only makes it special when looking at the pointed-to
object.
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <clive@davros.org>
Fax: +44 181 371 1037 | <clive@demon.net> | Abuse:
Written on my laptop; please observe the Reply-To address | <clive@bofh.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: chris.dearlove@gecm.com (Chris Dearlove)
Date: 1997/05/29 Raw View
I'll say it again, I'm just searching for enlightenment here. Roughly
I can't see why certain pointer comparisons can't be undefined. Mr.
Feather can, and I'm sure he's right, he just hasn't been able to
convince me (which is my loss, not his).
Clive D.W. Feather (clive@on-the-train.demon.co.uk) wrote:
: In article <5me5gu$358$1@miranda.gmrc.gecm.com>, Chris Dearlove
: <chris.dearlove@gecm.com> writes
: >:>the following comparisons are also possible
: >:>(d) Pointer past end of array with object not in array
: >:>(e) Pointer past end of array with another non-equal such pointer
: > it would be good to see an example,
: >ideally of a case where extra otherwise unnecessary contortions are
: >needed to avoid making a type (d) or type (e) comparison (I suspect an
: >example for (e) is easier, so one with (d) would be better to nail
: >the point).
: What about:
: int pointer_within (char *x, char *low, char *high)
: {
: char *p;
: for (p = low; p <= high; p++)
: if (x == p)
: return 1;
: return 0;
: }
: int main (void)
: {
: char s [1], t [10];
: return pointer_within (s, t, t + sizeof (t)) +
: pointer_within (t + 5, t + 2, t + 8);
: }
This code performs a comparison of s with t+10 (type (d)) which is, as
you say below, unspecified. More globally it's tring to ask if s is one of
t, t+1, ... t+10 which is one of those things man was not meant to
know. To my mind this code is an example of code which shouldn't
be written (only the first function call of the return from main).
Having re-read what I asked for I didn't say this, but what I really
meant was "an example of code which is (reasonably) good practice and
would have to be made more complex - or would be impossible - if
type (d) or (e) comparisons were undefined".
This comes from my (slightly naive) view of undefined behaviour as
"instances where we permit the compiler to do anything it likes
because it would be too much work for it and/or us to decide what
it should so, and furthermore this doesn't matter because if you
write code which does this you're only getting what you deserve"
: >and the question about ... code, because a "natural" implementation
: >which took no special action might or might not execute the code.
: >From this I went to the thought that (in code with any pretentions
: >to portability, conformance etc.) such a comparison was a Bad Thing
: Yes, because it is unspecified whether or not they are equal.
: >and to the question could/should it be undefined.
: No, because the pointers may have come via some intermediate variable;
: you can't know whether they are into an array or to one-past-the-end.
Couldn't you use the same argument to say that in the code
int foo(int *x, int *y)
{
return ++*x + ++*y;
}
you can't tell whether x and y point to the same object and hence
whether behaviour is undefined. In this case
int main(void)
{
int a = 1;
int b = 2;
return foo(&a, &b);
}
does not exhibit undefined behaviour, but
int main(void)
{
int a = 1;
return foo(&a, &a);
}
does, and no one is (or at least ought to be) unhappy with that.
--
Christopher M. Dearlove, | chris.dearlove@gecm.com
GEC-Marconi Research Centre, | Tel: 01245 242194 Int: +44 1245 242194
Gt. Baddow, Chelmsford, CM2 8HN, UK | Fax: 01245 242124 Int: +44 1245 242124
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Dr A. N. Walker" <anw@maths.nottingham.ac.uk>
Date: 1997/05/30 Raw View
Clive D.W. Feather wrote [reformatted for brevity -- ANW]:
> int main (void) {
> int *p;
> { int a; p = &a; }
> { int b; return (p == &b); }
> }
If the assignment to "p" isn't illegal [and I bow to Clive's
superior knowledge of the C?++ standard], then it darn well ought to
be! It's 22 years since Algol forbade assignments to pointers of
wider scope than the object pointed at, thereby preventing a whole
slew of really obscure program bugs.
--
Andy Walker, Maths Dept., Nott'm Univ., UK.
anw@maths.nott.ac.uk
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Martin D Kealey <martin@kcbbs.gen.nz>
Date: 1997/05/30 Raw View
In article <338DBD25.41C6@maths.nott.ac.uk>,
Dr A. N. Walker (anw@maths.nottingham.ac.uk) wrote:
> Clive D.W. Feather wrote [reformatted for brevity -- ANW]:
>> int main (void) {
>> int *p;
>> { int a; p = &a; }
>> { int b; return (p == &b); }
>> }
> If the assignment to "p" isn't illegal [and I bow to Clive's
> superior knowledge of the C?++ standard], then it darn well ought to
> be! It's 22 years since Algol forbade assignments to pointers of
> wider scope than the object pointed at, thereby preventing a whole
> slew of really obscure program bugs.
While that sounds like a really admirable objective, sometimes it is a
pivotal point of some useful techniques (see below). All that happens
if you make it illegal to do it directly is that the programmer has to
jump through hoops to make it happen, which only serves to obfusticate
the code.
And then there is the question of what happens to the legality of the
program if you do jump through such hoops; the normal thing in C/C++ is
that if you aren't allowed to do something, but you manage to do it
anyway by hiding it from the compiler, then you're invoking undefined
behaviour. Not to do so in this case would be rather inconsistent:
it could lead to code which being considered valid on a "simple"
compiler, and invalid on a more sophisticated one that can spot what
you're trying to do; I do not think that type of ambiguity should
be allowed in the standard.
The archetypal case where stashing a pointer to some auto object is
where it's going to be used in some function several nesting levels
deep, while clearly the object still exists. Algol can perform the same
thing without assigning out of scope because the nest functions can be
brought into scope. Arguably it can be done by passing parameters, but
if you're enough levels down that overhead might be intolerable for
some applications.
I suppose we could formulate a requirement that only says you can't
leave the pointer pointing at an auto object when you return from a
function, but in all except the trivial cases it would be pretty hard to
detect. At least this lesser requirement would still allow the above
technique, while allowing "undefined behaviour" for other cases.
The one case it *would* be guaranteed to catch is actually returning the
address of an auto object.
-Martin.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: schwab@issan.informatik.uni-dortmund.de (Andreas Schwab)
Date: 1997/05/30 Raw View
Julian Pardoe <pardoej@lonnds.ml.com> writes:
|> The following code
|> struct Foo *a = malloc (sizeof (struct Foo));
|> struct Foo *b = malloc (sizeof (struct Foo));
|> assert (a != b);
|> must pass the assertion-test
No. Both can be NULL.
--
Andreas Schwab "And now for something
schwab@issan.informatik.uni-dortmund.de completely different"
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: antispam.icedancer@antispam.ibm.net (Ken Walter)
Date: 1997/06/02 Raw View
In message <338DBD25.41C6@maths.nott.ac.uk> - "Dr A. N. Walker"
<anw@maths.nottingham.ac.uk> writes:
>
> Clive D.W. Feather wrote [reformatted for brevity -- ANW]:
>
> > int main (void) {
> > int *p;
> > { int a; p = &a; }
> > { int b; return (p == &b); }
> > }
>
> If the assignment to "p" isn't illegal [and I bow to Clive's
> superior knowledge of the C?++ standard], then it darn well ought to
> be! It's 22 years since Algol forbade assignments to pointers of
> wider scope than the object pointed at, thereby preventing a whole
> slew of really obscure program bugs.
But Algol had to carry around the stack frame pointer with any pointer
to check and Algol didn't have dynamically allocated data (new/delete)
which could go away at any time. For that you would need a capability
architecture with unique object ids that were essentially never reused
so that when the object went away the pointer was automatically
invalid. This leads to lookup tables and unique id garbage collection
etc.
Been down that path, was very interesting but expensive.
Ken Walter (Remove antispam. from address)
All the above is hearsay and the opinion of no one in particular.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Clive D.W. Feather" <clive@on-the-train.demon.co.uk>
Date: 1997/06/02 Raw View
In article <199705300809.UAA25135@kcbbs.gen.nz>, Martin D Kealey
<martin@kcbbs.gen.nz> writes
>it could lead to code which being considered valid on a "simple"
>compiler, and invalid on a more sophisticated one that can spot what
>you're trying to do; I do not think that type of ambiguity should
>be allowed in the standard.
Why not ? You've just described one of the reasons behind "undefined
behaviour".
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <clive@davros.org>
Fax: +44 181 371 1037 | <clive@demon.net> | Abuse:
Written on my laptop; please observe the Reply-To address | <clive@bofh.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Tom Payne <thp@cs.ucr.edu>
Date: 1997/06/03 Raw View
James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
: So I'm assuming editorial error, and supposing that what is meant is the
: same guarantees as in the C standard. And the C standard:
: 1. allows comparison between any valid pointer, although it doesn't
: always define what the results of that comparison will be.
: 2. defines the results of a certain number of comparisons for equality
: where the pointers do NOT point within the same object.
: The only real problem that I see is that it never guarantees that two
: pointers to different objects compare unequal.
The editorial omission seems minor. Per 6.3.9: "If two pointers to
object or incomplete types compare equal, they both are null pointers,
or both point to the same object [whatever that means], or both point
one past the last element of the same array object." Presumably, this
should have been bi-conditional (i.e., "If and only if ... .") so
that, when both pointers aren't null and don't point to the same
object and don't point one past the last element of the same array,
then they don't compare equal, i.e., they compare unequal. (They must
return some result by #1 above, and that result is either zero or
non-zero.)
My problem, however, is with the concept of "same object," which seems
to involve sameness of addresses, i.e., equality of pointers. Does
this ill-founded circularity bother others? It's no doubt possible,
though tedious, to replace it with a recursive definition, i.e.,
well-founded circularity.
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Clive D.W. Feather" <clive@on-the-train.demon.co.uk>
Date: 1997/06/03 Raw View
In article <5mjj26$okt$1@miranda.gmrc.gecm.com>, Chris Dearlove
<chris.dearlove@gecm.com> writes
>I'll say it again, I'm just searching for enlightenment here. Roughly
>I can't see why certain pointer comparisons can't be undefined. Mr.
>Feather can, and I'm sure he's right, he just hasn't been able to
>convince me (which is my loss, not his).
Very simply, the authors of the Standard (almost certainly following K&R
and common practice) took the view that pointers are such a core part of
the language, and get handed around all over the place, that it is
*always* useful to be able know if two pointers are the same.
This requires that *no* equality comparison is undefined, given only
that you have valid pointers in the first place.
>This code performs a comparison of s with t+10 (type (d)) which is, as
>you say below, unspecified. More globally it's tring to ask if s is one of
>t, t+1, ... t+10 which is one of those things man was not meant to
>know. To my mind this code is an example of code which shouldn't
>be written
Funny: whenever I use this argument, I get shouted at :-)
>Having re-read what I asked for I didn't say this, but what I really
>meant was "an example of code which is (reasonably) good practice and
>would have to be made more complex - or would be impossible - if
>type (d) or (e) comparisons were undefined".
Any code that does pointer comparison, and accepts arbitrary pointers
from elsewhere.
I suspect that "good practice" code is going to be large and complex,
because *simple* suggestions can easiy be rewritten. But, off the top of
my head, a malloc wrapper library with checking, or something similar,
is likely to be hard to write without this.
>: No, because the pointers may have come via some intermediate variable;
>: you can't know whether they are into an array or to one-past-the-end.
>
>Couldn't you use the same argument to say that in the code
>int foo(int *x, int *y)
>{
> return ++*x + ++*y;
>}
>you can't tell whether x and y point to the same object and hence
>whether behaviour is undefined.
But there is a simple way to work around this problem. On the other
hand, how else can you *tell* if x and y point to the same object
without comparing them ? [Yes, I know that if x points to one past the
end, I can't take *x; that's not the issue.]
Here's another example:
int f (char *p, char *q)
{
/* Placeholder for anything that compares pointers */
return p == q;
}
int main (int argc, char *argv [])
{
char c [5][5];
int i = 0, j = 0, k = 0;
/* Placeholder for getting arbitrary valid values for i, j, k */
if (argc > 1) i = atoi (argv [1]) % 6;
if (argc > 2) j = atoi (argv [2]) % 6;
if (argc > 3) k = atoi (argv [3]) % 6;
assert (i >= 0 && j >= 0 && k >= 0);
/* The nub of the matter */
return f (c [i], c [j] + k);
}
Consider the following inputs:
2 2 0
2 1 5
2 3 0
2 2 5
Explain why the second of each pair should be undefined if the first
isn't (hint, f can't tell the difference).
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <clive@davros.org>
Fax: +44 181 371 1037 | <clive@demon.net> | Abuse:
Written on my laptop; please observe the Reply-To address | <clive@bofh.org>
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Tom Payne <thp@cs.ucr.edu>
Date: 1997/05/25 Raw View
In comp.std.c++ Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote:
[...]
: The reason why I even consider the possibility that a compiler might
: overlap the storage, even though the addresses are taken (and then compared),
: is that you have allowed the possibility that a pointer to one thing
: might also be a pointer to something else. If you allow that possibility,
: then in order to disallow such dubious compiler optimizations, you need
: to find a requirement somewhere that a pointer to one object cannot also
: be a pointer to a different object.
I'd like to be able to insist that two objects are the same object if
and only if they have the same address and type. The term "same
address" is problematical, however, since per 6.3.8: "If the objects
pointed to are not members of the same aggregate or union object, the
result [of pointer comparision] is undefined ..."
As you've pointed out, C/C++ does not prohibit the overlapping of the
post-final (virtual) member of one array with the first member of
another. To rule out a comparison between these members of different
aggregates, one must insist that whether or not a pointer expression
points to a member of a particular aggregate depends not only on the
value of that expression but also on its form.
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Clive D.W. Feather" <clive@on-the-train.demon.co.uk>
Date: 1997/05/26 Raw View
In article <5m1t0k$nu0@mulga.cs.mu.OZ.AU>, Fergus Henderson
<fjh@mundook.cs.mu.OZ.AU> writes
>When I said "`x' and `y' are never used at the same time", I was
>talking about the values stored in them being used, not about
>their addresses being used.
I once wrote a DR for the C Standard that asked about something like:
void f (void)
{
int a, b;
/* Do various things with a */
if (&a == &b)
printf ("They're the same");
/* Do various things with b */
}
Because a and b are never used at the same time, a compiler could easily
optimize them into the same memory location.
WG14 stated that, nevertheless, the two objects must have different
addresses.
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <clive@davros.org>
Fax: +44 181 371 1037 | <clive@demon.net> | Abuse:
Written on my laptop; please observe the Reply-To address | <clive@bofh.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/05/26 Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
|> However, so long as you don't use vendor extensions, then the standard
|> ought to guarantee that pointers to different functions compare unequal.
|> The current C++ draft doesn't do that.
<smiley mode on>
Which should simplify one aspect of implementing inline functions. The
draft does require that the address of the inline function always
compare equal, regardless of the compilation unit in which it was
taken. So an implementation could just define that all comparisons
between pointers to functions return equal, and there's one less
difficulty to solve.
Now if there were only an equally simple solution for local static
variables...
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/05/26 Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
|> chris.dearlove@gecm.com (Chris Dearlove) writes:
|>
|> >Considering comparisons of pointers for equality/inequality only there are
|> >the following sorts of comparisons possible which must be permitted
|> >
|> >(a) Pointer to object with pointer to object
|> >(b) Pointer past end of array with pointer to object in array
|> >(c) Pointer past end of array with itself
|> >
|> >the following comparisons are also possible
|> >
|> >(d) Pointer past end of array with object not in array
|> >(e) Pointer past end of array with another non-equal such pointer
|> >
|> >where I mean whatever the standard (not to hand) actually permits as
|> >"pointer past end of array".
|> >
|> >My question is would it matter if the results of (d) and (e) were
|> >explicitly undefined?
|>
|> Well, I agree that (d) should be explcitly undefined.
|> But I think (e) ought to be defined.
|>
|> >If not then it would be easy to say (a) was
|> >true iff the objects were equal (b) was false and (c) was true.
|>
|> I think that the solutions to the problems I've been talking about
|> in this thread are indeed pretty easy, and even non-controversial.
Let's just not forget the other special case, string literals, while
we're at it. If both pointers point into string literals, the results
are undefined. (And I would argue that if one pointer points into a
string literal, and the other doesn't, the results should be false.
Which they will be on all real implementations, even if the standard
doesn't require it.)
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/05/26 Raw View
Tom Payne <thp@cs.ucr.edu> writes:
|> In comp.std.c++ Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote:
|> [...]
|> : The C standard does specify a few more details about the semantics
|> : of pointer equality operations other than that quoted above in 6.3.9[4];
|> : it goes on to say the following:
|>
|> : | 6.3.9 Equality Operators
|> : | ...
|> : | [5] ... If two pointers to object or incomplete types compare
|> : | equal, they both are null pointers, or both point to the same object, or both
|> : | point one past the last element of the same array object.
|>
|> : But this does not make it clear whether the comparison `&x == &y' from
|> : the above example results in undefined behaviour. The definition of
|> : undefined behaviour says "undefined behaviour is ... indicated ... by
|> : the omission of any explicit definition of behaviour". Does 6.3.9[5]
|> : constitute an "explicit definition of behaviour"? If so, the two
|> : pointers must compare unequal. If not, all bets are off.
|>
|> According to 6.3.8, a pointer comparison elicits undefined behavior,
|> unless the objects pointed to are members of the same aggregate or
|> union object. In such a case, the result is EQUAL if and only if the
|> objects pointed to are the same object. (For these purposes an
|> virtual member is appended to each array.) In all other cases,
|> undefined behavior ensues, and the result is irrelevant ---
|> specifically, a result of EQUAL will not rescue behavior that already
|> undefined.
I think that we are agreed that this is just an editorial error in the
C++ draft standard. The C++ standard has two base documents, the ARM
and the C standard; if something in the draft disagrees with both, it
should normally have been the object of a proposal and a vote in the
standards committee. I don't think that this is the case here.
Something got lost somewhere in rewording; now that the editors have
been made aware of this, I'm certain that it will get back in.
So I'm assuming editorial error, and supposing that what is meant is the
same guarantees as in the C standard. And the C standard:
1. allows comparison between any valid pointer, although it doesn't
always define what the results of that comparison will be.
2. defines the results of a certain number of comparisons for equality
where the pointers do NOT point within the same object.
The only real problem that I see is that it never guarantees that two
pointers to different objects compare unequal. The only problem I see
in correcting this to pay attention so as to not guarantee things that
most implementations don't provide, e.g.: the results of comparing a
pointer to one past the end of an array with another object, or of
comparing two pointers into string literals.
The effect of this is, I believe, the same as John Potter's proposal to
require that pointers to different bytes compare unequal.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: msb@sq.com (Mark Brader)
Date: 1997/05/26 Raw View
Paul DeRocco:
> > Therefore, barring bizarre casts and other subversive activities, two
> > pointers that point to different non-nested objects cannot compare equal.
Clive Feather:
> int main (void)
> {
> int *p;
>
> {
> int a;
> p = &a;
> }
I think Paul's "subversive activities" can reasonably be understood to
include anything that causes undefined behavior. By 6.1.2.4/3.1.2.4,
upon departure from this inner block, storage for "a" is no longer
guaranteed to be reserved, and the value of p is indeterminate.
(I'm speaking of C here, though I doubt C++ would differ in this respect!)
> {
> int b;
> return (p == &b);
Therefore, by 3.16/1.6, this reference to p causes undefined behavior.
> }
> }
> Hmm.
"Hmm"?
Side comment: in postings, please remember to avoid variable names that
are English words. It forces awkward punctuation if one is to avoid
creating parsing difficulties when talking about them.
--
Mark Brader "Sir, your composure baffles me. A single counter-
msb@sq.com example refutes a conjecture as effectively as ten.
SoftQuad Inc. ... Hands up! You have to surrender."
Toronto -- Imre Lakatos
My text in this article is in the public domain.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@strip_these_words.ix.netcom.com>
Date: 1997/05/27 Raw View
Clive D.W. Feather wrote:
>
> I once wrote a DR for the C Standard that asked about something like:
>
> void f (void)
> {
> int a, b;
>
> /* Do various things with a */
> if (&a == &b)
> printf ("They're the same");
> /* Do various things with b */
> }
>
> Because a and b are never used at the same time, a compiler could easily
> optimize them into the same memory location.
>
> WG14 stated that, nevertheless, the two objects must have different
> addresses.
I would expect this to be covered by the "as if" rule. You'd expect that
two different variables would have two different addresses, but the
compiler should be allowed to perform the optimization you suggested as
long as the program continues to behave as if it didn't. As soon as you
compare the two pointers, however, this would introduce a difference in
the behavior of the program, so the compiler would no longer be allowed
to make that optimization.
--
Ciao,
Paul
(Please remove the "strip_these_words." prefix from the return
address, which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: chris.dearlove@gecm.com (Chris Dearlove)
Date: 1997/05/27 Raw View
Clive D.W. Feather (clive@on-the-train.demon.co.uk) wrote:
: In article <5m0voe$r5j$1@miranda.gmrc.gecm.com>, Chris Dearlove
: <chris.dearlove@gecm.com> writes
: >the following comparisons are also possible
: >
: >(d) Pointer past end of array with object not in array
: >(e) Pointer past end of array with another non-equal such pointer
: These are also well defined.
: >My question is would it matter if the results of (d) and (e) were
: >explicitly undefined?
: Yes.
: The whole point of the one-past-the-end rule is to allow the end of an
: array *not* to be a special case.
Whilst not doubting you at all it would be good to see an example,
ideally of a case where extra otherwise unnecessary contortions are
needed to avoid making a type (d) or type (e) comparison (I suspect an
example for (e) is easier, so one with (d) would be better to nail
the point). A was coming at it from starting from the previous
example of
{
int x[1], y[1];
if (x+1 == y)
{
...
}
}
and the question about ... code, because a "natural" implementation
which took no special action might or might not execulte the code.
Author: "Clive D.W. Feather" <clive@on-the-train.demon.co.uk>
Date: 1997/05/28 Raw View
In article <338A7582.315A@strip_these_words.ix.netcom.com>, "Paul D.
DeRocco" <pderocco@strip_these_words.ix.netcom.com> writes
>> I once wrote a DR for the C Standard that asked about something like:
[...]
>> Because a and b are never used at the same time, a compiler could easily
>> optimize them into the same memory location.
>>
>> WG14 stated that, nevertheless, the two objects must have different
>> addresses.
>
>I would expect this to be covered by the "as if" rule. You'd expect that
>two different variables would have two different addresses, but the
>compiler should be allowed to perform the optimization you suggested as
>long as the program continues to behave as if it didn't. As soon as you
>compare the two pointers, however, this would introduce a difference in
>the behavior of the program, so the compiler would no longer be allowed
>to make that optimization.
Which is precisely what WG14 said.
Well, almost precisely - they can have the same address, so long as the
compiler fudges the comparison to make it look as if they don't.
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <clive@davros.org>
Fax: +44 181 371 1037 | <clive@demon.net> | Abuse:
Written on my laptop; please observe the Reply-To address | <clive@bofh.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/05/28 Raw View
"Paul D. DeRocco" <pderocco@strip_these_words.ix.netcom.com> writes:
|> Clive D.W. Feather wrote:
|> >
|> > I once wrote a DR for the C Standard that asked about something like:
|> >
|> > void f (void)
|> > {
|> > int a, b;
|> >
|> > /* Do various things with a */
|> > if (&a == &b)
|> > printf ("They're the same");
|> > /* Do various things with b */
|> > }
|> >
|> > Because a and b are never used at the same time, a compiler could easily
|> > optimize them into the same memory location.
|> >
|> > WG14 stated that, nevertheless, the two objects must have different
|> > addresses.
|>
|> I would expect this to be covered by the "as if" rule. You'd expect that
|> two different variables would have two different addresses, but the
|> compiler should be allowed to perform the optimization you suggested as
|> long as the program continues to behave as if it didn't. As soon as you
|> compare the two pointers, however, this would introduce a difference in
|> the behavior of the program, so the compiler would no longer be allowed
|> to make that optimization.
It's even more subtle than that. For example, in the above example, the
compiler could notice that the standard requires the expression to
evaluate false, and generate the code accordingly (without ever taking
the address of a or b), and still overlay a and b. In fact, in this
case, these are "standard" optimizations; I suspect that most compilers
would do them.
Assigning the address to a global pointer is more likely to inhibit the
optimization, but even then, if the compiler can assert that the pointer
is never actually used before the variable goes out of scope
(e.g. because "f" doesn't call any other function which could use it),
it could still overlay the two. In practice, I doubt that any compiler
does this.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Julian Pardoe <pardoej@lonnds.ml.com>
Date: 1997/05/28 Raw View
Tom Payne wrote:
> According to 6.3.8, a pointer comparison elicits undefined behavior,
> unless the objects pointed to are members of the same aggregate or
> union object. In such a case, the result is EQUAL if and only if the
> objects pointed to are the same object. (For these purposes an
> virtual member is appended to each array.) In all other cases,
> undefined behavior ensues, and the result is irrelevant
I will assume that you draw the conclusion that "the result is EQUAL
if and only if the objects pointed to are the same object" ****and
undefined otherwise****.
The point is that if this is a valid reading of the Standard then
the Standard is wrong -- or do I mean "wrong"?
The following code
struct Foo *a = malloc (sizeof (struct Foo));
struct Foo *b = malloc (sizeof (struct Foo));
assert (a != b);
must pass the assertion-test or else an assumption that almost
all C programmers have relied upon is invalidated. (The same applies
if the Foos are automatic or static.)
I believe it was the intention of the Standard that == and != be defined
in all cases where valid pointers ae compared. The restrictions about
pointing to the same object were supposed to reply to <, <= etc. If close
reading of the Standard does not justify this interoretation then the wording
of the Standard must be amended.
> specifically, a result of EQUAL will not rescue behavior that already
> undefined.
Nothing rescues behaviour that is already undefined!
-- jP --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@strip_these_words.ix.netcom.com>
Date: 1997/05/22 Raw View
Fergus Henderson wrote:
>
> However, if you allow the possibility that `x + 1', which is a pointer to
> one-past-the-end of the array `x', could _also_ be a pointer to the first
> element of `y', why stop there -- why not also allow the possibility that
> `x + 0', which is a pointer to the first element of the array `x', could
> also be a pointer to the first element of array `y'? For example, if the
> compiler can determine that `x' and `y' are never used at the same time,
> it could allocate them both to the same storage. So then, by this logic,
> the test
>
> int x[1], y[1];
> if (&x[0] == &y[0]) { ... }
>
> could succeed, because `x' and `y' might be allocated overlapping storage.
But when you write &x[0]==&y[0], you are using x and y at the same time,
and the compiler, according to your scenario, wouldn't allocate them at
the same address. The equality can only be true if you don't test it.
But if a tree falls in the forest...
--
Ciao,
Paul
(Please remove the "strip_these_words." prefix from the return
address, which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: smayo@ziplink.net (Scott Mayo)
Date: 1997/05/22 Raw View
In comp.std.c++,comp.std.c, fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) wrote:
<For example, if the
<compiler can determine that `x' and `y' are never used at the same time,
<it could allocate them both to the same storage. So then, by this logic,
<the test
< int x[1], y[1];
< if (&x[0] == &y[0]) { ... }
<could succeed, because `x' and `y' might be allocated overlapping storage.
Your x and y *are* used at the same time. Right in that if(). Any compiler
caught assuming otherwise gets hauled out and shot. Compliant or
otherwise.
--
Watch where you swing that optimizer, buddy!
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: chris.dearlove@gecm.com (Chris Dearlove)
Date: 1997/05/22 Raw View
Fergus Henderson (fjh@mundook.cs.mu.OZ.AU) wrote:
: So, another (philosophical) question for the comp.std.c people:
: is Paul D. DeRocco correct, i.e. can a single pointer point to
: both y and one-past-the-end of x? Or, should it be the case that each
: pointer points to only one thing, but that a pointer to y may compare
: equal with a pointer to one-past-the-end of x (even though conceptually
: they point to different things)?
Considering comparisons of pointers for equality/inequality only there are
the following sorts of comparisons possible which must be permitted
(a) Pointer to object with pointer to object
(b) Pointer past end of array with pointer to object in array
(c) Pointer past end of array with itself
the following comparisons are also possible
(d) Pointer past end of array with object not in array
(e) Pointer past end of array with another non-equal such pointer
where I mean whatever the standard (not to hand) actually permits as
"pointer past end of array".
My question is would it matter if the results of (d) and (e) were
explicitly undefined? If not then it would be easy to say (a) was
true iff the objects were equal (b) was false and (c) was true.
Please note this _is_ a question, not a proposal.
--
Christopher M. Dearlove, | chris.dearlove@gecm.com
GEC-Marconi Research Centre, | Tel: 01245 242194 Int: +44 1245 242194
Gt. Baddow, Chelmsford, CM2 8HN, UK | Fax: 01245 242124 Int: +44 1245 242124
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/05/23 Raw View
"Paul D. DeRocco" <pderocco@strip_these_words.ix.netcom.com> writes:
>Fergus Henderson wrote:
>
>> Yes, but there is still a problem in the current C++ draft here:
>> the current C++ draft does not require two pointers to different
>> functions to compare unequal.
>
>That can happen in a segmented architecture if you compare two near code
>pointers that happen to refer to different code segments. But as soon as
>a near pointer is used in a situation where there are multiple segments,
>it should be promoted to a far pointer by the programmer, to avoid
>losing the extra info.
Neither the C standard nor the C++ standard defines "near" or "far" pointers.
A C or C++ implementation must support a uniform model in which all pointers
to a given type are the same size. C/C++ implementations can offer "near"
and "far" pointers as extensions, but if you use those extensions, then
you are stepping out of what the standard guarantees and so the standard
doesn't impose any requirements.
However, so long as you don't use vendor extensions, then the standard
ought to guarantee that pointers to different functions compare unequal.
The current C++ draft doesn't do that.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/05/23 Raw View
chris.dearlove@gecm.com (Chris Dearlove) writes:
>Considering comparisons of pointers for equality/inequality only there are
>the following sorts of comparisons possible which must be permitted
>
>(a) Pointer to object with pointer to object
>(b) Pointer past end of array with pointer to object in array
>(c) Pointer past end of array with itself
>
>the following comparisons are also possible
>
>(d) Pointer past end of array with object not in array
>(e) Pointer past end of array with another non-equal such pointer
>
>where I mean whatever the standard (not to hand) actually permits as
>"pointer past end of array".
>
>My question is would it matter if the results of (d) and (e) were
>explicitly undefined?
Well, I agree that (d) should be explcitly undefined.
But I think (e) ought to be defined.
>If not then it would be easy to say (a) was
>true iff the objects were equal (b) was false and (c) was true.
I think that the solutions to the problems I've been talking about
in this thread are indeed pretty easy, and even non-controversial.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@strip_these_words.ix.netcom.com>
Date: 1997/05/23 Raw View
Chris Dearlove wrote:
>
> Considering comparisons of pointers for equality/inequality only there are
> the following sorts of comparisons possible which must be permitted
>
> (a) Pointer to object with pointer to object
> (b) Pointer past end of array with pointer to object in array
> (c) Pointer past end of array with itself
>
> the following comparisons are also possible
>
> (d) Pointer past end of array with object not in array
> (e) Pointer past end of array with another non-equal such pointer
>
> My question is would it matter if the results of (d) and (e) were
> explicitly undefined? If not then it would be easy to say (a) was
> true iff the objects were equal (b) was false and (c) was true.
>
> Please note this _is_ a question, not a proposal.
That looks fine to me. Remember, a pointer past the end of an array
doesn't actually point to an "object", since you aren't allowed to
dereference such a pointer. Therefore, barring bizarre casts and other
subversive activities, two pointers that point to different non-nested
objects cannot compare equal.
--
Ciao,
Paul
(Please remove the "strip_these_words." prefix from the return
address, which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1997/05/24 Raw View
On 19 May 1997 16:54:18 PDT, you wrote:
: In a thread crossposted to many (too many!) newsgroups, in an article with
: followups redirected to comp.std.{c,c++}, I wrote:
: >Neither the C standard nor the C++ draft working
: >paper guarantee that pointer equality tests will reflect object identity.
: To elaborate further, now that the discussion is in the appropriate newsgroups,
: the problem is that the C standard and C++ DWP both give the semantics
: for equality (== or !=) in terms of the semantics for the relational
: operators (<, <=, >, and >=). The results of the relational operators
: on pointers are defined only if the pointers point into the same object.
Let me try to be pragmatic on this. There is a memory model
consisting of bytes for both C and C++. The two problems involved are
pointers to the same byte and pointers to different bytes.
The practical problem involves the fact that the current wording
allows pointers to different bytes to compare equal. AFAIK there is
no implementation on which this happens. The standards should
disallow it.
The other problem involves pointers to the same byte within different
objects.
struct S1 {
int a;
float b;
};
struct S2 {
int c;
double d;
};
union U {
S1 s1;
S2 s2;
};
U u;
The draft assures that
static_cast<void*>(&u) ==
static_cast<void*>(&u.s1) ==
static_cast<void*>(&u.s2) ==
static_cast<void*>(&u.s1.a) ==
static_cast<void*>(&u.s2.c)
I do not care whether &u.s1.a == &u.s2.c
I do not care whether past the end of some array compares equal to
some other object.
I do not care whether two pointers with different values point to the
same byte but compare unequal. But this one is already covered by the
requirement that pointers into the same object compare properly. It
is normally assured by an implementation forcing only one possible
pointer to any given object. Machiavelli, you're on you're own.
I do not care if Machiavelli stores a pointer to a local variable in
two different functions in global variables and they later compare
equal.
IMHO, the simple requirement that pointers to two different bytes
never compare equal will fix all of the real problems. The other
wierd cases can be left unspecified.
We already have assurance that two pointers to the same object compare
equal and no pointer to object compares equal to the null pointer.
With this and the above, we should have practical object identity.
I await demonstration of the falicy in my simple logic,
John
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Tom Payne <thp@cs.ucr.edu>
Date: 1997/05/24 Raw View
In comp.std.c++ Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote:
[...]
: The C standard does specify a few more details about the semantics
: of pointer equality operations other than that quoted above in 6.3.9[4];
: it goes on to say the following:
: | 6.3.9 Equality Operators
: | ...
: | [5] ... If two pointers to object or incomplete types compare
: | equal, they both are null pointers, or both point to the same object, or both
: | point one past the last element of the same array object.
: But this does not make it clear whether the comparison `&x == &y' from
: the above example results in undefined behaviour. The definition of
: undefined behaviour says "undefined behaviour is ... indicated ... by
: the omission of any explicit definition of behaviour". Does 6.3.9[5]
: constitute an "explicit definition of behaviour"? If so, the two
: pointers must compare unequal. If not, all bets are off.
According to 6.3.8, a pointer comparison elicits undefined behavior,
unless the objects pointed to are members of the same aggregate or
union object. In such a case, the result is EQUAL if and only if the
objects pointed to are the same object. (For these purposes an
virtual member is appended to each array.) In all other cases,
undefined behavior ensues, and the result is irrelevant ---
specifically, a result of EQUAL will not rescue behavior that already
undefined.
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Clive D.W. Feather" <clive@on-the-train.demon.co.uk>
Date: 1997/05/25 Raw View
In article <5m0voe$r5j$1@miranda.gmrc.gecm.com>, Chris Dearlove
<chris.dearlove@gecm.com> writes
>Considering comparisons of pointers for equality/inequality only there are
>the following sorts of comparisons possible which must be permitted
>
>(a) Pointer to object with pointer to object
>(b) Pointer past end of array with pointer to object in array
>(c) Pointer past end of array with itself
Right. All are permitted.
>the following comparisons are also possible
>
>(d) Pointer past end of array with object not in array
>(e) Pointer past end of array with another non-equal such pointer
These are also well defined.
>My question is would it matter if the results of (d) and (e) were
>explicitly undefined?
Yes.
The whole point of the one-past-the-end rule is to allow the end of an
array *not* to be a special case.
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <clive@davros.org>
Fax: +44 181 371 1037 | <clive@demon.net> | Abuse:
Written on my laptop; please observe the Reply-To address | <clive@bofh.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Clive D.W. Feather" <clive@on-the-train.demon.co.uk>
Date: 1997/05/25 Raw View
In article <338543DF.625A@strip_these_words.ix.netcom.com>, "Paul D.
DeRocco" <pderocco@strip_these_words.ix.netcom.com> writes
>Therefore, barring bizarre casts and other
>subversive activities, two pointers that point to different non-nested
>objects cannot compare equal.
int main (void)
{
int *p;
{
int a;
p = &a;
}
{
int b;
return (p == &b);
}
}
Hmm.
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <clive@davros.org>
Fax: +44 181 371 1037 | <clive@demon.net> | Abuse:
Written on my laptop; please observe the Reply-To address | <clive@bofh.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/05/19 Raw View
In a thread crossposted to many (too many!) newsgroups, in an article with
followups redirected to comp.std.{c,c++}, I wrote:
>Neither the C standard nor the C++ draft working
>paper guarantee that pointer equality tests will reflect object identity.
To elaborate further, now that the discussion is in the appropriate newsgroups,
the problem is that the C standard and C++ DWP both give the semantics
for equality (== or !=) in terms of the semantics for the relational
operators (<, <=, >, and >=). The results of the relational operators
on pointers are defined only if the pointers point into the same object.
>From the C++ DWP:
| 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.
>From the C standard:
| 6.3.9 Equality Operators
| [4] Where the operands have types and values suitable for the relational
| operators, the semantics detailed in 6.3.8 apply.
The problem with this definition is that there is a very large amount of
code that relies on pointer equality comparisons reflecting object identity.
I continued:
>For example, given
>
> int x, y;
> if (&x == &y) ...
>
>then according to the current C++ draft working paper the result is
>unspecified.
>For the same example, the C standard is unclear; depending
>on how you interpret it, either
>(a) the pointer comparison results in undefined behaviour, or
>(b) the result is guaranteed to be false -- but then by the same
> interpretation, in the following example
> int xa[1], ya[1];
> if (xa + 1 == ya || xa == ya + 1) ...
> the condition is also guaranteed to be false, which would imply
> that most existing C implementations don't conform to the standard.
First question for the comp.std.c people: which is correct, (a), (b),
or something else?
The C standard does specify a few more details about the semantics
of pointer equality operations other than that quoted above in 6.3.9[4];
it goes on to say the following:
| 6.3.9 Equality Operators
| ...
| [5] ... If two pointers to object or incomplete types compare
| equal, they both are null pointers, or both point to the same object, or both
| point one past the last element of the same array object.
But this does not make it clear whether the comparison `&x == &y' from
the above example results in undefined behaviour. The definition of
undefined behaviour says "undefined behaviour is ... indicated ... by
the omission of any explicit definition of behaviour". Does 6.3.9[5]
constitute an "explicit definition of behaviour"? If so, the two
pointers must compare unequal. If not, all bets are off.
Consider also the following example:
int x[1], y[1];
if (x + 1 == y) {
...
}
Again it is not clear if the comparison results in undefined behaviour.
But in this case, if this is not undefined behaviour, then 6.3.9[5]
requires the pointers to compare unequal -- which would make existing
implementations non-conforming, since existing implementations
do not insert padding at the end of arrays to ensure that the address
one-past-the-end does not overlap with other objects.
I also claimed:
>[These problems are undoubtably unintentional mistakes in the C standard
>and the C++ DWP, and certainly don't reflect the true intent of the language
>designers or standards committees involved.]
Second question for the comp.std.c people: is this claim correct?
Is this indeed a defect in the C standard?
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Paul D. DeRocco" <strip_these_words_pderocco@ix.netcom.com>
Date: 1997/05/20 Raw View
Fergus Henderson wrote:
>
> The C standard does specify a few more details about the semantics
> of pointer equality operations other than that quoted above in 6.3.9[4];
> it goes on to say the following:
>
> | 6.3.9 Equality Operators
> | ...
> | [5] ... If two pointers to object or incomplete types compare
> | equal, they both are null pointers, or both point to the same object,
> | or both point one past the last element of the same array object.
>
> Consider also the following example:
>
> int x[1], y[1];
> if (x + 1 == y) {
> ...
> }
>
> Again it is not clear if the comparison results in undefined behaviour.
> But in this case, if this is not undefined behaviour, then 6.3.9[5]
> requires the pointers to compare unequal -- which would make existing
> implementations non-conforming, since existing implementations
> do not insert padding at the end of arrays to ensure that the address
> one-past-the-end does not overlap with other objects.
But if x+1==y, then x+1 and y _are_ both pointers to one-past-the-end of
x, and they _are_ both pointers to y. I don't see that what you've
quoted from the standard prohibits y from starting at the same address x
ends at.
--
Ciao,
Paul
(Please remove the "strip_these_words_" prefix from the return
address, which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: mschill@forte.com (Mike Schilling)
Date: 1997/05/20 Raw View
I presume the following should do "the right thing" also:
a.cc:
extern void *func();
void (*p)() = func;
check(p);
b.cc:
#include <stdio.h>
extern void *func();
void check(void (*p)())
{
if (p == func)
{
printf("Seems OK\n"):
}
else
{
printf("Dammit!\n");
}
}
Please forgive any typos. The intent is to pass a function pointer to
another function and see if it compares equal to itself. I know of
several platforms where this *doesn't* work correctly in the case where
a.cc and b.cc are linked into different executables, i.e. either one is in
a shared library or the two are in different shared libraries. The
problem is that "func" may point to the function itself or to a vector
which jumps to the the actual function.
Do you think this behavior should also be guaranteed by the Standards,
or is this a legitimate place for implementation-specific behavior?
My opinion is the former.
Feel free to post this, if you think that's appropriate. My %&*&*&
newsreader won't currently allow that. [Done. -mod]
Thanks,
Mike
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Steve Clamage <stephen.clamage@eng.sun.com>
Date: 1997/05/21 Raw View
Mike Schilling wrote:
>
> I presume the following should do "the right thing" also:
>
> ...
>
> Please forgive any typos. The intent is to pass a function pointer to
> another function and see if it compares equal to itself. I know of
> several platforms where this *doesn't* work correctly in the case where
> a.cc and b.cc are linked into different executables, i.e. either one is in
> a shared library or the two are in different shared libraries. The
> problem is that "func" may point to the function itself or to a vector
> which jumps to the the actual function.
>
> Do you think this behavior should also be guaranteed by the Standards,
> or is this a legitimate place for implementation-specific behavior?
> My opinion is the former.
The C and C++ standards require that two pointers to the same function
compare equal to each other. In a given program, there can be only
one external function with a given signature. If you find that two
pointers to the same function in the same program do not compare equal,
the implementation is in error.
Notice I said "implementation". The problem might not be in the
compiler. The Solaris linker and dynamic loader, for example,
jump through hoops to be sure that all references to a given function
are resolved in the same way in any one program. The compiler in all
cases merely generates references to external functions.
--
Steve Clamage, stephen.clamage@eng.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/05/21 Raw View
Steve Clamage <stephen.clamage@eng.sun.com> writes:
>Mike Schilling wrote:
>>
>> I presume the following should do "the right thing" also:
...
>> The intent is to pass a function pointer to
>> another function and see if it compares equal to itself. I know of
>> several platforms where this *doesn't* work correctly in the case where
>> a.cc and b.cc are linked into different executables, i.e. either one is in
>> a shared library or the two are in different shared libraries.
...
>The C and C++ standards require that two pointers to the same function
>compare equal to each other.
Yes, but there is still a problem in the current C++ draft here:
the current C++ draft does not require two pointers to different
functions to compare unequal.
>In a given program, there can be only
>one external function with a given signature. If you find that two
>pointers to the same function in the same program do not compare equal,
>the implementation is in error.
But only, of course, if it claims to conform to the standard.
An implementation might well claim to be standard-conforming,
and to support DLLs, but if you read the fine print it might
say that these two are mutually exclusive :-(
Oh well, I guess Microsoft are not really reknowned for standards
conformance...
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/05/21 Raw View
"Paul D. DeRocco" <strip_these_words_pderocco@ix.netcom.com> writes:
>Fergus Henderson wrote:
> >
> > The C standard:
> > | 6.3.9 Equality Operators
> > | ...
> > | [5] ... If two pointers to object or incomplete types compare
> > | equal, they both are null pointers, or both point to the same object,
> > | or both point one past the last element of the same array object.
> >
> > Consider also the following example:
> >
> > int x[1], y[1];
> > if (x + 1 == y) {
> > ...
> > }
> >
> > Again it is not clear if the comparison results in undefined behaviour.
> > But in this case, if this is not undefined behaviour, then 6.3.9[5]
> > requires the pointers to compare unequal -- which would make existing
> > implementations non-conforming, since existing implementations
> > do not insert padding at the end of arrays to ensure that the address
> > one-past-the-end does not overlap with other objects.
>
>But if x+1==y, then x+1 and y _are_ both pointers to one-past-the-end of
>x, and they _are_ both pointers to y.
[Short Answer:]
Yes, you're probably right.
[Long Answer:]
Ah. That interpretation does make quite a bit of sense.
I was implicitly assuming that when the standard said
"... the result is a pointer to <blah>" that that was the _only_
thing it pointed to. But perhaps that assumption is not correct.
However, if you allow the possibility that `x + 1', which is a pointer to
one-past-the-end of the array `x', could _also_ be a pointer to the first
element of `y', why stop there -- why not also allow the possibility that
`x + 0', which is a pointer to the first element of the array `x', could
also be a pointer to the first element of array `y'? For example, if the
compiler can determine that `x' and `y' are never used at the same time,
it could allocate them both to the same storage. So then, by this logic,
the test
int x[1], y[1];
if (&x[0] == &y[0]) { ... }
could succeed, because `x' and `y' might be allocated overlapping storage.
So, another (philosophical) question for the comp.std.c people:
is Paul D. DeRocco correct, i.e. can a single pointer point to
both y and one-past-the-end of x? Or, should it be the case that each
pointer points to only one thing, but that a pointer to y may compare
equal with a pointer to one-past-the-end of x (even though conceptually
they point to different things)?
Hmm... perhaps I'm being overly pedantic here -- I guess some of these
interpretations are a bit strained. I guess that's the trouble with
natural language standards, they're always open to interpretation.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/05/22 Raw View
"Paul D. DeRocco" <pderocco@strip_these_words.ix.netcom.com> writes:
>Fergus Henderson wrote:
>>
>> However, if you allow the possibility that `x + 1', which is a pointer to
>> one-past-the-end of the array `x', could _also_ be a pointer to the first
>> element of `y', why stop there -- why not also allow the possibility that
>> `x + 0', which is a pointer to the first element of the array `x', could
>> also be a pointer to the first element of array `y'? For example, if the
>> compiler can determine that `x' and `y' are never used at the same time,
>> it could allocate them both to the same storage. So then, by this logic,
>> the test
>>
>> int x[1], y[1];
>> if (&x[0] == &y[0]) { ... }
>>
>> could succeed, because `x' and `y' might be allocated overlapping storage.
>
>But when you write &x[0]==&y[0], you are using x and y at the same time,
>and the compiler, according to your scenario, wouldn't allocate them at
>the same address.
When I said "`x' and `y' are never used at the same time", I was
talking about the values stored in them being used, not about
their addresses being used.
The reason why I even consider the possibility that a compiler might
overlap the storage, even though the addresses are taken (and then compared),
is that you have allowed the possibility that a pointer to one thing
might also be a pointer to something else. If you allow that possibility,
then in order to disallow such dubious compiler optimizations, you need
to find a requirement somewhere that a pointer to one object cannot also
be a pointer to a different object.
Well, anyway as I said in my last post this line of argument is a bit
strained and I won't pursue it.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@strip_these_words.ix.netcom.com>
Date: 1997/05/22 Raw View
Fergus Henderson wrote:
> Yes, but there is still a problem in the current C++ draft here:
> the current C++ draft does not require two pointers to different
> functions to compare unequal.
That can happen in a segmented architecture if you compare two near code
pointers that happen to refer to different code segments. But as soon as
a near pointer is used in a situation where there are multiple segments,
it should be promoted to a far pointer by the programmer, to avoid
losing the extra info. Comparing two near pointers into different
segments is no more valid than testing to see if two 32-bit integers are
equal by first casting them to 16-bit shorts. Mixing near and far
pointers requires programmer intelligence, and is beyond what the
standard can specify.
--
Ciao,
Paul
(Please remove the "strip_these_words." prefix from the return
address, which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]