Topic: Dereferencing a null-pointer allowed?
Author: luri@gmx.li (Lutz Richter)
Date: Tue, 8 May 2007 17:53:17 GMT Raw View
Hi,
given the following code:
-----------------------------
class B
{
public:
B(): Value(99) {}
int Get() { if (this) return Value; else return -1; }
private:
int Value;
};
int main()
{
B* b = 0;
cout << b->Get();
}
-----------------------------
I wonder if this is allowed. I did not have any problem with any
compiler yet. It works! But is this guaranteed?
Unfortunately Stroustrop & Co. do not mention this problem in their
books. If anyone has a documentation about NOT doing the above example,
then please tell me.
Thanks in advance, Lutz.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Hyman Rosen <hyrosen@mail.com>
Date: Tue, 8 May 2007 13:16:22 CST Raw View
Lutz Richter wrote:
> int Get() { if (this) return Value; else return -1; }
This is legal, but a good compiler will elide the test and
assume that 'this' is always non-null.
> B* b = 0; cout << b->Get();
This is undefined behavior, because you may not indirect
through a null pointer.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Tue, 8 May 2007 15:03:25 CST Raw View
> I wonder if this is allowed. I did not have any problem with any
> compiler yet. It works! But is this guaranteed?
>
> Unfortunately Stroustrop & Co. do not mention this problem in their
> books. If anyone has a documentation about NOT doing the above example,
> then please tell me.
As Hyman Rosen explained, it causes UB, what you do above.
Since you asked additionally for a reference, here we go:
1.9/4:
"Certain other operations are described in this International Standard
as
undefined (for example, the effect of dereferencing the null pointer).
[..]"
5.2.5/3:
"If E1 has the type "pointer to class X," then the expression E1->E2
is
converted to the equivalent form (*(E1)).E2;[..]"
5.3.1/1:
"The unary * operator performs indirection: the expression to which it
is
applied shall be a pointer to an object type, or a pointer to a
function
type and the result is an lvalue referring to the object or function
to
which the expression points.[..]"
8.3.2/4:
"[..] Note: in particular, a null reference cannot exist in a well-
defined
program, because the only way to create such a reference would be
to bind it to the "object" obtained by dereferencing a null pointer,
which causes undefined behavior."
So yes, the essence is rather distributed among the standard, but
it is clearly expressed that you cannot use the dereferenced result
of an object pointer to access its members.
Greetings from Bremen,
Daniel Kr gler
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: ok_nospam_ok@phoyd.net (Marco Manfredini)
Date: Thu, 10 May 2007 03:56:11 GMT Raw View
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D MODERATOR'S COMMENT:=20
(Apologies for this comment, which is present to bypass broken
spam filtering implemented by Cox.)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D END OF MODERATOR'S COMMENT
Daniel Kr=FCgler wrote:
> 5.3.1/1:
> "The unary * operator performs indirection: the expression to which it
> is
> applied shall be a pointer to an object type, or a pointer to a
> function
> type and the result is an lvalue referring to the object or function
~~~~~~
> to
> which the expression points.[..]"
>=20
> 8.3.2/4:
> "[..] Note: in particular, a null reference cannot exist in a well-
~~~~~~~~~
> defined
> program, because the only way to create such a reference would be
> to bind it to the "object" obtained by dereferencing a null pointer,
> which causes undefined behavior."
>=20
> So yes, the essence is rather distributed among the standard, but
> it is clearly expressed that you cannot use the dereferenced result
> of an object pointer to access its members.
lvalues are not references - The same paragraph says, that you can not
form a reference to a bit field member, but bit fields members make
perfect lvalues.
=20
Marco
--=20
// MUST be set to 1!
Params->ParentalLevel =3D 3; // QA now insist this is set to 2.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Wed, 9 May 2007 22:56:05 CST Raw View
===================================== MODERATOR'S COMMENT:
(Apologies for this comment, which is present to bypass broken
spam filtering implemented by Cox.)
===================================== END OF MODERATOR'S COMMENT
On May 8, 11:03 pm, Daniel Kr gler <daniel.krueg...@googlemail.com>
wrote:
> So yes, the essence is rather distributed among the standard, but
> it is clearly expressed that you cannot use the dereferenced result
> of an object pointer to access its members.
With one important exception, I believe: if the expression is
used as an argument to sizeof or typeid. Something like:
sizeof( ((T*)0)->f() )
is legal, I think.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Thu, 10 May 2007 06:23:23 CST Raw View
===================================== MODERATOR'S COMMENT:
===================================== END OF MODERATOR'S COMMENT
> Daniel Kr gler wrote:
> > 5.3.1/1:
> > "The unary * operator performs indirection: the expression to which it
> > is
> > applied shall be a pointer to an object type, or a pointer to a
> > function
> > type and the result is an lvalue referring to the object or function
>
> ~~~~~~> to
> > which the expression points.[..]"
>
> > 8.3.2/4:
> > "[..] Note: in particular, a null reference cannot exist in a well-
>
> ~~~~~~~~~
>
> > defined
> > program, because the only way to create such a reference would be
> > to bind it to the "object" obtained by dereferencing a null pointer,
> > which causes undefined behavior."
>
> > So yes, the essence is rather distributed among the standard, but
> > it is clearly expressed that you cannot use the dereferenced result
> > of an object pointer to access its members.
>
> lvalues are not references - The same paragraph says, that you can not
> form a reference to a bit field member, but bit fields members make
> perfect lvalues.
I did not claim anything in the way you interpret it
here and I also did not relate that to lvalues, I just
quoted the note of 8.3.2/4, because it argues that
the act of creating a null reference would imply to
bind it to the "object" obtained by dereferencing
a null pointer. The last point is relevant for this
discussion, nothing more.
Greetings from Bremen,
Daniel Kr gler
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Thu, 10 May 2007 06:23:15 CST Raw View
===================================== MODERATOR'S COMMENT:
===================================== END OF MODERATOR'S COMMENT
On May 10, 6:56 am, James Kanze <james.ka...@gmail.com> wrote:
> On May 8, 11:03 pm, Daniel Kr gler <daniel.krueg...@googlemail.com>
> wrote:
>
> > So yes, the essence is rather distributed among the standard, but
> > it is clearly expressed that you cannot use the dereferenced result
> > of an object pointer to access its members.
>
> With one important exception, I believe: if the expression is
> used as an argument to sizeof or typeid. Something like:
> sizeof( ((T*)0)->f() )
> is legal, I think.
I tried to exclude your example by saying "cannot use".
I meant "use" here in the way defined by 3.2/2:
"An expression is potentially evaluated unless it appears
where an integral constant expression is required (see 5.19),
is the operand of the sizeof operator (5.3.3), or is the
operand of the typeid operator and the expression does not
designate an lvalue of polymorphic class type (5.2.8).
An object or non-overloaded function is used if its name
appears in a potentially-evaluated expression."
Obviously my wording was not unmistakably, so thanks
for this point, James!
Greetings,
Daniel
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Ron Natalie <ron@spamcop.net>
Date: Thu, 10 May 2007 07:06:05 CST Raw View
===================================== MODERATOR'S COMMENT:
===================================== END OF MODERATOR'S COMMENT
James Kanze wrote:
>
> With one important exception, I believe: if the expression is
> used as an argument to sizeof or typeid. Something like:
> sizeof( ((T*)0)->f() )
> is legal, I think.
>
Correct, sizeof doesn't evaluate it's argument, it merely
checks the type.
Typeid does however potentially do so, since the result
may be something it has to test the dynamic typing of.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Greg Herlihy <greghe@pacbell.net>
Date: Thu, 10 May 2007 11:26:21 CST Raw View
On May 10, 6:06 am, Ron Natalie <r...@spamcop.net> wrote:
> James Kanze wrote:
>
> > With one important exception, I believe: if the expression is
> > used as an argument to sizeof or typeid. Something like:
> > sizeof( ((T*)0)->f() )
> > is legal, I think.
>
> Correct, sizeof doesn't evaluate it's argument, it merely
> checks the type.
>
> Typeid does however potentially do so, since the result
> may be something it has to test the dynamic typing of.
Nonetheless, dereferencing a null pointer in a typeid expression has
well-defined behavior - the result is a thrown bad_typeid exception,
per 5.2.8/2.
Greg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: jdennett@acm.org (James Dennett)
Date: Fri, 11 May 2007 07:03:04 GMT Raw View
Greg Herlihy wrote:
> On May 10, 6:06 am, Ron Natalie <r...@spamcop.net> wrote:
>> James Kanze wrote:
>>
>>> With one important exception, I believe: if the expression is
>>> used as an argument to sizeof or typeid. Something like:
>>> sizeof( ((T*)0)->f() )
>>> is legal, I think.
>> Correct, sizeof doesn't evaluate it's argument, it merely
>> checks the type.
>>
>> Typeid does however potentially do so, since the result
>> may be something it has to test the dynamic typing of.
>=20
> Nonetheless, dereferencing a null pointer in a typeid expression has
> well-defined behavior - the result is a thrown bad_typeid exception,
> per =A75.2.8/2.
I don't think that can be right; at least not without
qualification. typeid(*expr) is well-defined even if
expr is a null pointer, but if expr itself includes
a dereference operation on a null pointer (and the
typeid requires runtime evaluation) then the behavior
can still be undefined, just as if expr were evaluated
in any other context.
-- James
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Fri, 11 May 2007 11:37:33 CST Raw View
On May 10, 7:26 pm, Greg Herlihy <gre...@pacbell.net> wrote:
> On May 10, 6:06 am, Ron Natalie <r...@spamcop.net> wrote:
> > James Kanze wrote:
> > > With one important exception, I believe: if the expression is
> > > used as an argument to sizeof or typeid. Something like:
> > > sizeof( ((T*)0)->f() )
> > > is legal, I think.
> > Correct, sizeof doesn't evaluate it's argument, it merely
> > checks the type.
> > Typeid does however potentially do so, since the result
> > may be something it has to test the dynamic typing of.
> Nonetheless, dereferencing a null pointer in a typeid expression has
> well-defined behavior - the result is a thrown bad_typeid exception,
> per 5.2.8/2.
No. The only case that happens is if the argument to typeid is
an lvalue expression which "is obtained by applying * to a
pointer". In an example such at the above (replacing sizeof
with typeid), if the return type of T::f() is anything but a
reference to a polymorphique type, the expression is not
evaluated, at all. If the return type is a reference to a
polymorphic object, then the expression is evaluated, and we get
undefined behavior (probably a core dump if T::f() is virtual,
or uses the contents of the class in any way).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: W Karas <wkaras@yahoo.com>
Date: Fri, 11 May 2007 15:13:36 CST Raw View
On May 8, 1:53 pm, l...@gmx.li (Lutz Richter) wrote:
> Hi,
>
> given the following code:
>
> -----------------------------
> class B
> {
> public:
> B(): Value(99) {}
> int Get() { if (this) return Value; else return -1; }
>
> private:
> int Value;
>
> };
>
> int main()
> {
> B* b = 0;
> cout << b->Get();}
>
> -----------------------------
>
> I wonder if this is allowed. I did not have any problem with any
> compiler yet. It works! But is this guaranteed?
>
> Unfortunately Stroustrop & Co. do not mention this problem in their
> books. If anyone has a documentation about NOT doing the above example,
> then please tell me.
>
> Thanks in advance, Lutz.
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]
(Resend this, my apologies if it is a duplicate)
This question touches on a broader issue: the C++ Standard is often
much more
strict than the de facto standard that can be inferred from the widely-
used C++
implementations.
I would guess that the above code would compile and run properly with
any
widely-used C++ compiler. To me personally, it would be much more
intuitive to do this kind of a test for null in a static class member
function
that took an instance pointer as an explicit parameter. So that
might be why the Standard is stricter in this case.
A more complicated case is the restrictions on memcpy-ing
objects to/from arrays of char. In de facto C++, this works fine
for objects of primitive type or any class with a valid default copy
constructor whose data members and base classes are
also memcpy-able. Standard C++ restricts memcpy-ing to
POD types. This has some advantages if the Standard
will someday use the concept of memcpy-ability to venture
into the untouched territories of binary secondary storage
and transfers in shared memory. But even then, the restriction
to POD only seems overly strict.
On the other hand, de facto C++ (in order to avoid
breaking old C code I would guess) can be restrictive
in perhaps undesirable ways. For example, if I write:
class X { char a; int i; char b; };
I've not seen any compilers that would store b
before i in the structure, even though this seems
to be ok under the Standard (?), although it
perhaps shouldn't be for POD.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Ron Natalie <ron@spamcop.net>
Date: Sat, 12 May 2007 16:47:49 CST Raw View
Greg Herlihy wrote:
> On May 10, 6:06 am, Ron Natalie <r...@spamcop.net> wrote:
>> James Kanze wrote:
>>
>>> With one important exception, I believe: if the expression is
>>> used as an argument to sizeof or typeid. Something like:
>>> sizeof( ((T*)0)->f() )
>>> is legal, I think.
>> Correct, sizeof doesn't evaluate it's argument, it merely
>> checks the type.
>>
>> Typeid does however potentially do so, since the result
>> may be something it has to test the dynamic typing of.
>
> Nonetheless, dereferencing a null pointer in a typeid expression has
> well-defined behavior - the result is a thrown bad_typeid exception,
> per 5.2.8/2.
>
Sort of...
That clause applies to something like this:
T* tp = 0;
typeid *tp;
Int he case of the expression written originally (substituting
typeid for sizeof) it's still undefined behavior.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Sat, 12 May 2007 16:47:35 CST Raw View
On May 11, 11:13 pm, W Karas <wka...@yahoo.com> wrote:
> On May 8, 1:53 pm, l...@gmx.li (Lutz Richter) wrote:
> > given the following code:
> > -----------------------------
> > class B
> > {
> > public:
> > B(): Value(99) {}
> > int Get() { if (this) return Value; else return -1; }
> > private:
> > int Value;
> > };
> > int main()
> > {
> > B* b = 0;
> > cout << b->Get();}
> > -----------------------------
> > I wonder if this is allowed. I did not have any problem with any
> > compiler yet. It works! But is this guaranteed?
> This question touches on a broader issue: the C++ Standard is
> often much more strict than the de facto standard that can be
> inferred from the widely- used C++ implementations.
That's partially true. Sometimes, it is because C++ tries to
remain implementable on more exotic architectures. Thus, you
will have no problems on most common architectures copying a
pointer after it has been used as the operand to delete, but
there are some exotic (and in the past not so exotic)
architectures where this might be more difficult to implement,
so C++ declares it undefined behavior. In other cases, the
standard's committee does end up standardizing existing
practice, once it becomes clear that it really is universal: the
next version of the standard will require the memory in
std::string to be contiguous, for example, and that <iostream>
actually include <istream>, <ostream>, etc. (When the last
version of the standard was adopted, no one had sufficient
experience with these issues to be sure that there might not be
cases where it was reasonable to do otherwise. Time has shown,
however, that there aren't.)
> I would guess that the above code would compile and run
> properly with any widely-used C++ compiler.
Unless, of course, the compiler was serious about optimization.
I can't imagine it running "correctly" (assuming that outputting
-1 is "correct") with any decent optimization. And of course,
even on compilers where it currently runs "correctly", it is
just a special case. Throw in multiple inheritance or virtual
functions, and it will do strange things with a lot of
compilers.
> On the other hand, de facto C++ (in order to avoid
> breaking old C code I would guess) can be restrictive
> in perhaps undesirable ways. For example, if I write:
> class X { char a; int i; char b; };
> I've not seen any compilers that would store b
> before i in the structure, even though this seems
> to be ok under the Standard (?), although it
> perhaps shouldn't be for POD.
It's forbidden. I think there is a DR concerning this, however.
Formally:
struct A { char a; int i; char b; } ;
// Order guaranteed.
struct B { public: char a; public: int i; public: char b; } ;
// Order not guaranteed.
In the latter case, however, B is still a POD.
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: e0226430@stud3.tuwien.ac.at (Sebastian Redl)
Date: Sun, 13 May 2007 14:49:29 GMT Raw View
On Fri, 11 May 2007, W Karas wrote:
> On the other hand, de facto C++ (in order to avoid
> breaking old C code I would guess) can be restrictive
> in perhaps undesirable ways. For example, if I write:
>
> class X { char a; int i; char b; };
>
> I've not seen any compilers that would store b
> before i in the structure, even though this seems
> to be ok under the Standard (?), although it
> perhaps shouldn't be for POD.
It's not. It's not ok for any class, because the standard requires that
contained objects without an access specifier between them have the same
ordering in memory as in source code.
Effectively, this means that for the above example, assert(&a < &b) is
guaranteed not to fire (since a and b are part of the same object, the
pointer comparison is defined).
The relevant specification can be found e.g. in 9.2/12 of the newest C++09
draft:
"Nonstatic data members of a (non-union) class declared without an
intervening access specifier are allocated so that later members have
higher addresses within a class object."
Sebastian Redl
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Sun, 13 May 2007 09:48:15 CST Raw View
On May 10, 3:06 pm, Ron Natalie <r...@spamcop.net> wrote:
> James Kanze wrote:
> > With one important exception, I believe: if the expression is
> > used as an argument to sizeof or typeid. Something like:
> > sizeof( ((T*)0)->f() )
> > is legal, I think.
> Correct, sizeof doesn't evaluate it's argument, it merely
> checks the type.
> Typeid does however potentially do so, since the result
> may be something it has to test the dynamic typing of.
Good point. But if I understand 5.2.8 correctly, this can only
happen in a case like the above if the return value is a
reference to a type having at least one virtual function. (Of
course, if I know the type, and it cannot be polymorphic, what's
the point of using typeid?) It's interesting to note that this
depends only on the return type of T::f()---whether T::f() is
virtual or not plays no role in the issue.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: W Karas <wkaras@yahoo.com>
Date: Sun, 13 May 2007 09:52:09 CST Raw View
On May 12, 6:47 pm, James Kanze <james.ka...@gmail.com> wrote:
> On May 11, 11:13 pm, W Karas <wka...@yahoo.com> wrote:
> > On May 8, 1:53 pm, l...@gmx.li (Lutz Richter) wrote:
> > > given the following code:
> > > -----------------------------
> > > class B
> > > {
> > > public:
> > > B(): Value(99) {}
> > > int Get() { if (this) return Value; else return -1; }
> > > private:
> > > int Value;
> > > };
> > > int main()
> > > {
> > > B* b = 0;
> > > cout << b->Get();}
> > > -----------------------------
.
> > I would guess that the above code would compile and run
> > properly with any widely-used C++ compiler.
>
> Unless, of course, the compiler was serious about optimization.
> I can't imagine it running "correctly" (assuming that outputting
> -1 is "correct") with any decent optimization. And of course,
> even on compilers where it currently runs "correctly", it is
> just a special case.
Using a compiler that's about 4 years old (that generally
seems to optimize well), the check for null this was
retained in the object code.
> Throw in multiple inheritance or virtual
> functions, and it will do strange things with a lot of
> compilers.
Good point -- I would guess it would break in these cases
with all widely-used compilers. A better reason to make
it undefined than the one I mentioned.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: e0226430@stud3.tuwien.ac.at (Sebastian Redl)
Date: Mon, 14 May 2007 02:10:02 GMT Raw View
On Sun, 13 May 2007, W Karas wrote:
> On May 12, 6:47 pm, James Kanze <james.ka...@gmail.com> wrote:
>
> Using a compiler that's about 4 years old (that generally
> seems to optimize well), the check for null this was
> retained in the object code.
>
I should point out that the implementation of a popular GUI class library
shipped with a popular compiler that's about 4 years old intentionally
calls methods (even virtual ones, non-virtually by explicitly qualifying
them) on null pointers and uses if(this == 0) inside the member. So some
compilers are bound by backwards compatibility.
Sebastian Redl
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Mon, 14 May 2007 11:42:27 CST Raw View
On 13 Mai, 16:49, e0226...@stud3.tuwien.ac.at (Sebastian Redl) wrote:
> The relevant specification can be found e.g. in 9.2/12 of the newest C++09
> draft:
>
> "Nonstatic data members of a (non-union) class declared without an
> intervening access specifier are allocated so that later members have
> higher addresses within a class object."
I'm not sure why you put the emphasis on the
upcoming standard, so I would like to add the
remark, that the very same sentence already
exists at the same para and with unchanged
wording in the current standard 14882-2003.
Greetings from Bremen,
Daniel Kr gler
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Sebastian Redl <e0226430@stud3.tuwien.ac.at>
Date: Mon, 14 May 2007 21:47:45 CST Raw View
On Mon, 14 May 2007, [iso-8859-1] Daniel Kr gler wrote:
> I'm not sure why you put the emphasis on the
> upcoming standard, so I would like to add the
> remark, that the very same sentence already
> exists at the same para and with unchanged
> wording in the current standard 14882-2003.
I did it because I don't have the final version of the standard, only the
'97 public draft. And also because I had the new draft open at that time.
Sebastian Redl
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]