Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

why use int

1 view
Skip to first unread message

David R Tribble

unread,
Aug 11, 1999, 3:00:00 AM8/11/99
to
Francis Glassborow wrote:
>
> In article <37AF736A...@tribble.com>, David R Tribble
> <da...@tribble.com> writes
> >Many constants qualify, which is part of the problem.
> >
> > #define NULL ((void*)0)
> > #define NULL 0
> > #define NULL 0L
> > #define NULL (3-3)
> > #define NULL (0/1)
> > #define NULL '\0'
> > #define NULL ((int)0.1)
> > #define NULL enum_null
> >
> >Only the first one is proper, in my opinion, but ISO allows all of
> >them.
>
> And FWIW explicitly fails in C++ where type safety prohibits implicit
> conversion from void *

Yes, as I've stated many times before, the situation for NULL is
even worse in C++ than in C. While C can survive quite nicely with
'((void*)0)', C++ really would benefit having a true 'null'.

-- David R. Tribble, da...@tribble.com --
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]

Anders J. Munch

unread,
Aug 12, 1999, 3:00:00 AM8/12/99
to

David R Tribble wrote in message <37B08CE9...@tribble.com>...
[...]

>Yes, as I've stated many times before, the situation for NULL is
>even worse in C++ than in C. While C can survive quite nicely with
>'((void*)0)', C++ really would benefit having a true 'null'.


'((void*)0)' evaluates to a null pointer constant. In what sense is this
not a true 'null'?

- Anders

Steve Clamage

unread,
Aug 12, 1999, 3:00:00 AM8/12/99
to

"Anders J. Munch" <ande...@dancontrol.dk> writes:

>David R Tribble wrote in message <37B08CE9...@tribble.com>...
>[...]
>>Yes, as I've stated many times before, the situation for NULL is
>>even worse in C++ than in C. While C can survive quite nicely with
>>'((void*)0)', C++ really would benefit having a true 'null'.

>'((void*)0)' evaluates to a null pointer constant. In what sense is this
>not a true 'null'?

The C++ standard defines a null pointer constant as follows
(section 4.10):
"A null pointer constant is an integral constant expression (5.19)
rvalue of integer type that evaluates to zero."

You might be thinking of C, which allows implicit conversions
from void* to any other pointer type. In C, ((void*)0) is
allowed as a null pointer constant for that reason. In C++,
((void*)0) would not be useful as a null pointer constant:
T* p = ((void*)0); // error, unless T is type void

--
Steve Clamage, stephen...@sun.com

Christopher Eltschka

unread,
Aug 13, 1999, 3:00:00 AM8/13/99
to
[I removed the C newsgroups, since I'm only talking about C++]

Steve Clamage wrote:
>
> "Anders J. Munch" <ande...@dancontrol.dk> writes:
>
> >David R Tribble wrote in message <37B08CE9...@tribble.com>...
> >[...]
> >>Yes, as I've stated many times before, the situation for NULL is
> >>even worse in C++ than in C. While C can survive quite nicely with
> >>'((void*)0)', C++ really would benefit having a true 'null'.
>
> >'((void*)0)' evaluates to a null pointer constant. In what sense is this
> >not a true 'null'?
>
> The C++ standard defines a null pointer constant as follows
> (section 4.10):
> "A null pointer constant is an integral constant expression (5.19)
> rvalue of integer type that evaluates to zero."
>
> You might be thinking of C, which allows implicit conversions
> from void* to any other pointer type. In C, ((void*)0) is
> allowed as a null pointer constant for that reason. In C++,
> ((void*)0) would not be useful as a null pointer constant:
> T* p = ((void*)0); // error, unless T is type void

Is there a reason why C++ did not make a special rule for
((void*)0) as well as for literal 0?

BTW, there could be another solution: I've once suggested
a pointer type any*, which would be quite the opposite of
C++'s void*, in that implicit conversion _from_ any* _to_ T*,
but not vice versa exists. This would be handy for allocation
functions (like "any* malloc(size_t)" instead of
"void* malloc(size_t)") - allowing code like
"char* p=malloc(10);" to compile in C++, which is the use
I had in mind. But it would also automatically give a
convenient null pointer constant: ((any*)0).

any* would be sort of the other side of C's void*.
Especially all typesafe things which can be done with void*
in C would be possible by using void* or any* as appropriate
in C++. If neither void* nor any* would work, it would be
a potential non-typesafety, and therefore it would be good
that a cast is required.

The C++ functions which should return any* are

any* std::malloc(size_t)
any* std::calloc(size_t, size_t)
any* ::operator new(size_t)
any* ::operator new(size_t, std::nothrow_t)
any* ::operator new(size_t, void*)
any* ::operator new[](size_t);
any* ::operator new[](size_t, std::nothrow)
any* ::operator new[](size_t, void*)

You may have noticed that placement new still takes void here,
since placement new is IMHO sort of "converting" something into
raw memory, to construct objects in it.

Also, realloc is left out on purpose, since realloc usually
operates on memory which already has data of a given type;
converting that back to any* would compromise type safety
(converting to void* does too, but at least you have to
make that explicit by casting to the right type).
---

Anders J. Munch

unread,
Aug 13, 1999, 3:00:00 AM8/13/99
to
Steve Clamage wrote in message <7oupgk$nef$1...@engnews1.eng.sun.com>...

>
>"Anders J. Munch" <ande...@dancontrol.dk> writes:

>[...]


>>'((void*)0)' evaluates to a null pointer constant. In what sense is this
>>not a true 'null'?
>
>The C++ standard defines a null pointer constant as follows
>(section 4.10):
>"A null pointer constant is an integral constant expression (5.19)
>rvalue of integer type that evaluates to zero."
>
>You might be thinking of C, which allows implicit conversions
>from void* to any other pointer type. In C, ((void*)0) is
>allowed as a null pointer constant for that reason. In C++,
>((void*)0) would not be useful as a null pointer constant:
> T* p = ((void*)0); // error, unless T is type void


Hmm... you're not saying that
class A; class B;
assert(reinterpret_cast<A*>(static_cast<B*>(0)) == static_cast<A*>(0));
might fail? That is, different data objects can have different null pointer
representations that do not compare equal?

I wasn't thinking of C, I was thinking that void* resembles a pointer to a
superclass common to all types. "T* p = ((void*)0);" is then a downcast and
fails; but "void* p = new T;" is an upcast and succeeds. You're right
though, this doesn't make ((void*)0) a null pointer, as far as the type
system goes.

But that still doesn't answer my question on what a "true 'null'" would look
like. Something like this?

template <typename T>
inline T* nil() { return static_cast<T*>(0); }

class A;
A* p = nil<A>();

Or something like this?

A* p = nil;
B* q = nil;

If this is what David is looking for, why not instead legalize assigning a
null pointer compile-time constant of type void* to any pointer type:
A* p = (void*)0; // legal: type is void* and value is constant null
B* q = (void*)p; // illegal: type is void* but value is not a
compile-time constant

This will make a sensible definition of NULL possible:
const void* NULL = 0;
or the good old
#define NULL ((void*)0)

- Anders

Fergus Henderson

unread,
Aug 13, 1999, 3:00:00 AM8/13/99
to

cla...@eng.sun.com (Steve Clamage) writes:

>"Anders J. Munch" <ande...@dancontrol.dk> writes:
>

>>David R Tribble wrote in message <37B08CE9...@tribble.com>...
>>[...]
>>>Yes, as I've stated many times before, the situation for NULL is
>>>even worse in C++ than in C. While C can survive quite nicely with
>>>'((void*)0)', C++ really would benefit having a true 'null'.
>

>>'((void*)0)' evaluates to a null pointer constant. In what sense is this
>>not a true 'null'?
>
>The C++ standard defines a null pointer constant as follows
>(section 4.10):
>"A null pointer constant is an integral constant expression (5.19)
>rvalue of integer type that evaluates to zero."

Yes. This was a gratuitous change from C with significant drawbacks
and no advantages.

>You might be thinking of C, which allows implicit conversions
>from void* to any other pointer type. In C, ((void*)0) is
>allowed as a null pointer constant for that reason.

I take objection to the words "for that reason" here.
In C, `(void *)0' is allowed as a null pointer constant.
But it would make perfect sense to allow `(void *)0' as a null
pointer constant even if the language didn't allow implicit
conversions from `void *' to any other pointer type.

>In C++,
>((void*)0) would not be useful as a null pointer constant:
> T* p = ((void*)0); // error, unless T is type void

C++ already allows conversion from a null pointer constant to any
pointer type. So if C++ had defined "null pointer constant" in the
same way as C, then that code would not be an error.

Your argument here is circular, and silly. It's like saying that
"//" comments in C would not be useful, because they would be a syntax error.

--
Fergus Henderson <f...@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 f...@128.250.37.3 | -- the last words of T. S. Garp.

Steve Clamage

unread,
Aug 14, 1999, 3:00:00 AM8/14/99
to
"Anders J. Munch" <ande...@dancontrol.dk> writes:

>Steve Clamage wrote in message <7oupgk$nef$1...@engnews1.eng.sun.com>...
>>

>>"Anders J. Munch" <ande...@dancontrol.dk> writes:

>>[...]


>>>'((void*)0)' evaluates to a null pointer constant. In what sense is this
>>>not a true 'null'?
>>
>>The C++ standard defines a null pointer constant as follows
>>(section 4.10):
>>"A null pointer constant is an integral constant expression (5.19)
>>rvalue of integer type that evaluates to zero."
>>

>>You might be thinking of C, which allows implicit conversions
>>from void* to any other pointer type. In C, ((void*)0) is

>>allowed as a null pointer constant for that reason. In C++,


>>((void*)0) would not be useful as a null pointer constant:
>> T* p = ((void*)0); // error, unless T is type void

>Hmm... you're not saying that


> class A; class B;
> assert(reinterpret_cast<A*>(static_cast<B*>(0)) == static_cast<A*>(0));
>might fail? That is, different data objects can have different null pointer

>representations ...

Pointers to different objects can in general have different
sizes and representations. The effects of a reinterpret_cast
are up to the implemenation. You cannot assume a priori that
it will or will not change the representation of a pointer.

> ... that do not compare equal?

You cannot compare values that are of different types. They must
be brought to a common type. Some conversions are implicit, others
require an explicit cast, still others cannot be performed at all.
Converting any value from one type to another might change its
size or representation.

There are some additional requirements on pointers, however.

All null pointers that can be compared must compare equal. (But
converting an A* to a B* before the comparison might change the
representation.)

Type void* must have the property that, for any object type T:
T* tp1 = ...; // any valid value for a T*
void* vp = tp1;
T* tp2 = static_cast<T*>(vp);
assert(tp1==tp2); // must not fail

Various other requirements on pointers (especially the ability
of a class pointer to point to any derived class) imply that all
pointers to class types must have the same size and representation.

--
Steve Clamage, stephen...@sun.com
---

Pete Becker

unread,
Aug 14, 1999, 3:00:00 AM8/14/99
to
Fergus Henderson wrote:

>
> cla...@eng.sun.com (Steve Clamage) writes:
>
> >The C++ standard defines a null pointer constant as follows
> >(section 4.10):
> >"A null pointer constant is an integral constant expression (5.19)
> >rvalue of integer type that evaluates to zero."
>
> Yes. This was a gratuitous change from C with significant drawbacks
> and no advantages.
>

This was not a gratuitous change. It was a consequence of the decision
that pointers to void do not implicitly convert to pointers to other
types. You've made it clear that you think that this change was carried
too far, but that's a different matter. Please stop misstating the
issue.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com

raw...@my-deja.com

unread,
Aug 14, 1999, 3:00:00 AM8/14/99
to
In article <37B43BC9...@acm.org>,

Pete Becker <peteb...@acm.org> wrote:
> Fergus Henderson wrote:
> >
> > cla...@eng.sun.com (Steve Clamage) writes:
> >
> > >The C++ standard defines a null pointer constant as follows
> > >(section 4.10):
> > >"A null pointer constant is an integral constant expression (5.19)
> > >rvalue of integer type that evaluates to zero."
> >
> > Yes. This was a gratuitous change from C with significant drawbacks
> > and no advantages.
> >
>
> This was not a gratuitous change. It was a consequence of the decision
> that pointers to void do not implicitly convert to pointers to other
> types. You've made it clear that you think that this change was carried
> too far, but that's a different matter. Please stop misstating the
> issue.

But the same consequence should stem from not implicitly
converting integers to pointers. If 0 were used like a keyword
that has an integer zero meaning and a null pointer meaning
(in each pointer type), that would be one thing. But if I've
read the above quote correctly, then (1-1) is also a null
pointer constant, which seems rather dubious. If you're
going to allow integer expressions that convert to null
pointer constants, you might as well also make a special
exception for (void *) constants that evaluate to (void *)0
at compile time.

--
MJSR


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Pete Becker

unread,
Aug 16, 1999, 3:00:00 AM8/16/99
to
raw...@my-deja.com wrote:
>
> But the same consequence should stem from not implicitly
> converting integers to pointers. If 0 were used like a keyword
> that has an integer zero meaning and a null pointer meaning
> (in each pointer type), that would be one thing. But if I've
> read the above quote correctly, then (1-1) is also a null
> pointer constant, which seems rather dubious. If you're
> going to allow integer expressions that convert to null
> pointer constants, you might as well also make a special
> exception for (void *) constants that evaluate to (void *)0
> at compile time.
>

C++ is the same as C here. A major goal in the design of C++ was to make
as few changes as possible from C.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com

Fergus Henderson

unread,
Aug 16, 1999, 3:00:00 AM8/16/99
to
Pete Becker <peteb...@acm.org> writes:

>Fergus Henderson wrote:
>>
>> cla...@eng.sun.com (Steve Clamage) writes:
>>
>> >The C++ standard defines a null pointer constant as follows
>> >(section 4.10):
>> >"A null pointer constant is an integral constant expression (5.19)
>> >rvalue of integer type that evaluates to zero."
>>
>> Yes. This was a gratuitous change from C with significant drawbacks
>> and no advantages.
>
>This was not a gratuitous change. It was a consequence of the decision
>that pointers to void do not implicitly convert to pointers to other
>types. You've made it clear that you think that this change was carried
>too far, but that's a different matter. Please stop misstating the issue.

Why was it a consequence of that decision?
As has been explained, the treatment of implicit conversions
and the definition of null pointer constant are independant.

I would be willing to accept "It was erroneously considered to be a
consequence ...". But my dictionary defines "gratuitous" as "uncalled
for, lacking good reason", and this seems quite apt. Erroneous
considerations such as this erroneous belief that the definition of
null pointer constant was consequent on the treatment of implicit
conversions one do not constitute "good reason". So I stand by my use
of the adjective "gratuitous".

Nevertheless, I did misstate the issue, albeit not in the way you are
suggesting. I should have said "This was a gratuitous difference from
ANSI C ..." rather than "This was a gratuitous change from C ...".
I apologize for that misstatement.

Bjarne's post explained that C++ started off being the same as K&R C,
and the special treatment for `(void *)0' in ANSI C came later, after
C++ had already forked off to become a new language. So it was a
difference from ANSI C, rather than from C, and the change that created
the difference was apparently made by the ANSI C committee rather than
by Bjarne. This makes it much more understandable. Still, there was
plenty of time for Bjarne and/or the C++ committee to remedy that;
as soon as people started having trouble with NULL being defined as
`(void *)0' in standard header files, C++ should have adopted the same
definition for null pointer constant as in ANSI C. C++ did after all
adopt pretty much everything else in ANSI C. So I still consider this
one to be a gratuitous difference from ANSI C.

--
Fergus Henderson <f...@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 f...@128.250.37.3 | -- the last words of T. S. Garp.

blargg

unread,
Aug 16, 1999, 3:00:00 AM8/16/99
to

In article <7p4mkn$7hl$1...@nnrp1.deja.com>, raw...@my-deja.com wrote:

[snip]


> If 0 were used like a keyword
> that has an integer zero meaning and a null pointer meaning
> (in each pointer type), that would be one thing. But if I've
> read the above quote correctly, then (1-1) is also a null
> pointer constant, which seems rather dubious.

[snip]

void* null = !! !! !! !! !! !! !!!
!!! !! !! !! !! !! !!!
!!!! !! !! !! !! !! !!!
!! !! !! !! !! !! !! !!!
!! !!!! !! !! !! !! !!!
!! !!! !! !! !! !! !
!! !! !!!! !!!!! !!!!! 0;

:-)

Fergus Henderson

unread,
Aug 16, 1999, 3:00:00 AM8/16/99
to

Pete Becker <peteb...@acm.org> writes:

>raw...@my-deja.com wrote:
>>
>> But the same consequence should stem from not implicitly

>> converting integers to pointers. If 0 were used like a keyword


>> that has an integer zero meaning and a null pointer meaning
>> (in each pointer type), that would be one thing. But if I've
>> read the above quote correctly, then (1-1) is also a null

>> pointer constant, which seems rather dubious. If you're
>> going to allow integer expressions that convert to null
>> pointer constants, you might as well also make a special
>> exception for (void *) constants that evaluate to (void *)0
>> at compile time.
>
>C++ is the same as C here. A major goal in the design of C++ was to make
>as few changes as possible from C.

But C++ is _not_ the same as ANSI/ISO C here!

C++ may be the same as K&R C here. But originally C didn't have `void'
at all. Surely the goal should have been to minimize the number of
differences from ANSI C, not the number of differences from K&R C.

--
Fergus Henderson <f...@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 f...@128.250.37.3 | -- the last words of T. S. Garp.

Francis Glassborow

unread,
Aug 16, 1999, 3:00:00 AM8/16/99
to

In article <7p88pd$av7$1...@mulga.cs.mu.OZ.AU>, Fergus Henderson
<f...@cs.mu.OZ.AU> writes

>C++ did after all
>adopt pretty much everything else in ANSI C. So I still consider this
>one to be a gratuitous difference from ANSI C.

And one that we could correct? Technically such a correction would be a
pure extension (something that is generally not allowed via DRs and the
consequential TCs) but seeing that part of our mandate was to stay as
close to C as ... I would support such a DR on the grounds that we did
not properly carry out that mandate.


Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Bjarne Stroustrup

unread,
Aug 16, 1999, 3:00:00 AM8/16/99
to

From: f...@cs.mu.OZ.AU (Fergus Henderson) writes:


> I would be willing to accept "It was erroneously considered to be a
> consequence ...". But my dictionary defines "gratuitous" as "uncalled
> for, lacking good reason", and this seems quite apt. Erroneous
> considerations such as this erroneous belief that the definition of
> null pointer constant was consequent on the treatment of implicit
> conversions one do not constitute "good reason". So I stand by my use
> of the adjective "gratuitous".
>
> Nevertheless, I did misstate the issue, albeit not in the way you are
> suggesting. I should have said "This was a gratuitous difference from
> ANSI C ..." rather than "This was a gratuitous change from C ...".
> I apologize for that misstatement.
>
> Bjarne's post explained that C++ started off being the same as K&R C,
> and the special treatment for `(void *)0' in ANSI C came later, after
> C++ had already forked off to become a new language. So it was a
> difference from ANSI C, rather than from C, and the change that created
> the difference was apparently made by the ANSI C committee rather than
> by Bjarne. This makes it much more understandable.

Yes. C++ compatibility wasn't/isn't a major concern of the C committee
(though I think that it ought to be for the best of the C and C++ communities).


> Still, there was
> plenty of time for Bjarne and/or the C++ committee to remedy that;
> as soon as people started having trouble with NULL being defined as
> `(void *)0' in standard header files, C++ should have adopted the same

> definition for null pointer constant as in ANSI C. C++ did after all


> adopt pretty much everything else in ANSI C. So I still consider this
> one to be a gratuitous difference from ANSI C.

At best (void*)0 as a special case would be yet another ugly wart. It
might do the job, but I would expect everybody to hide that wart in
a NULL macro.

Maybe "there was plenty of time for Bjarne and/or the C++ committee to
remedy that". However, I didn't notice C's use of (void*) in NULL until
quite late in the C++ standards process (I don't have much reason
to write C) where the committee was busy with the long lists of requests
from national standards bodies. I don't recall anyone proposing (void*)0
in the committee (I learned about it informally from Tom Plum and documented
it in D&E). In particular, I did not see it among the Australian proposals.

Fingerpointing years after an event is less than helpful because it can
sour the relations needed to make progress in the future.

- Bjarne
Bjarne Stroustrup - http://www.research.att.com/~bs

raw...@my-deja.com

unread,
Aug 16, 1999, 3:00:00 AM8/16/99
to
In article <37B5E4AC...@acm.org>,

Pete Becker <peteb...@acm.org> wrote:
> raw...@my-deja.com wrote:
> >
> > But the same consequence should stem from not implicitly
> > converting integers to pointers. If 0 were used like a keyword
> > that has an integer zero meaning and a null pointer meaning
> > (in each pointer type), that would be one thing. But if I've
> > read the above quote correctly, then (1-1) is also a null
> > pointer constant, which seems rather dubious. If you're
> > going to allow integer expressions that convert to null
> > pointer constants, you might as well also make a special
> > exception for (void *) constants that evaluate to (void *)0
> > at compile time.
> >
>
> C++ is the same as C here. A major goal in the design of C++ was to make
> as few changes as possible from C.

So an implementer could use #define NULL ((void *)0) in standard
headers and it would work in C++ implementations just as it works
in C? Sorry, I must have misunderstood the earlier posts.

--
MJSR


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---

Pete Becker

unread,
Aug 17, 1999, 3:00:00 AM8/17/99
to
Fergus Henderson wrote:
>
> Pete Becker <peteb...@acm.org> writes:
>
> >Fergus Henderson wrote:
> >>
> >> cla...@eng.sun.com (Steve Clamage) writes:
> >>
> >> >The C++ standard defines a null pointer constant as follows
> >> >(section 4.10):
> >> >"A null pointer constant is an integral constant expression (5.19)
> >> >rvalue of integer type that evaluates to zero."
> >>
> >> Yes. This was a gratuitous change from C with significant drawbacks
> >> and no advantages.
> >
> >This was not a gratuitous change. It was a consequence of the decision
> >that pointers to void do not implicitly convert to pointers to other
> >types. You've made it clear that you think that this change was carried
> >too far, but that's a different matter. Please stop misstating the issue.
>
> Why was it a consequence of that decision?
> As has been explained, the treatment of implicit conversions
> and the definition of null pointer constant are independant.

Exactly: the decision to change the treatment of implicit conversions
did not affect the definition of null pointer constant. It did affect
the meaning of a common form of definition for the C macro NULL.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com

Pete Becker

unread,
Aug 17, 1999, 3:00:00 AM8/17/99
to
raw...@my-deja.com wrote:
>
> In article <37B5E4AC...@acm.org>,
> Pete Becker <peteb...@acm.org> wrote:
> > raw...@my-deja.com wrote:
> > >
> > > But the same consequence should stem from not implicitly
> > > converting integers to pointers. If 0 were used like a keyword
> > > that has an integer zero meaning and a null pointer meaning
> > > (in each pointer type), that would be one thing. But if I've
> > > read the above quote correctly, then (1-1) is also a null
> > > pointer constant, which seems rather dubious. If you're
> > > going to allow integer expressions that convert to null
> > > pointer constants, you might as well also make a special
> > > exception for (void *) constants that evaluate to (void *)0
> > > at compile time.
> > >
> >
> > C++ is the same as C here. A major goal in the design of C++ was to make
> > as few changes as possible from C.
>
> So an implementer could use #define NULL ((void *)0) in standard
> headers and it would work in C++ implementations just as it works
> in C? Sorry, I must have misunderstood the earlier posts.
>

No, I said "as few changes as possible," not "no changes." One of the
major goals of C++ was type safety, and a consequence of that is that a
pointer to void cannot be implicitly converted to a pointer to some
other type.

James...@dresdner-bank.com

unread,
Aug 17, 1999, 3:00:00 AM8/17/99
to
In article <FGKDx...@research.att.com>,
b...@research.att.com (Bjarne Stroustrup) wrote:

> Maybe "there was plenty of time for Bjarne and/or the C++ committee to
> remedy that". However, I didn't notice C's use of (void*) in NULL
until
> quite late in the C++ standards process (I don't have much reason
> to write C) where the committee was busy with the long lists of
requests
> from national standards bodies.

Note too that C's use of (void*)0 was only introduced because that is
the form that most Intel compilers used. And that they used that form
so that things like execl( ... , NULL ) would work regardless of the
compilation model (and despite the fact that formally, they are
incorrect anyway).

> I don't recall anyone proposing (void*)0 in the committee (I learned
> about it informally from Tom Plum and documented it in D&E). In
> particular, I did not see it among the Australian proposals.

I wrote up a formal proposal, which was presented to one of the working
groups by Dag Bruck.

> Fingerpointing years after an event is less than helpful because it
> can sour the relations needed to make progress in the future.

Agreed. The proposal was rejected. It's not the only proposal that was
rejected -- either I didn't argue my point well enough, or it really
isn't as important as I thought. At any rate, I accept the committees
decision.

--
James Kanze mailto: James...@dresdner-bank.com
Conseils en informatique orientie objet/
Beratung in objekt orientierter Datenverarbeitung
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Francis Glassborow

unread,
Aug 17, 1999, 3:00:00 AM8/17/99
to
In article <37B8C0E8...@acm.org>, Pete Becker <peteb...@acm.org>
writes

>No, I said "as few changes as possible," not "no changes." One of the
>major goals of C++ was type safety, and a consequence of that is that a
>pointer to void cannot be implicitly converted to a pointer to some
>other type.

Much as I respect your opinions, I have to add that neither can any
integer type be converted implicitly to any pointer type. Yet both C
and C++ make a specific exception for almost any compile time constant
inter expression that evaluates to zero. However C++ does not extend
this exception to (void*)0. I understand, and accept Bjarne's
explanation that this was a change in C after C++ had already been
designed, however we have other other more extensive changes to C++ over
the last 10 years (i.e. since the release of C89). If a proposal for
support for (void *)0 to be a null pointer constant in C++ was really
made, I for one, would love to know the rationale for its rejection.
Type safety just does not cut it.

BTW, even in C runtime evaluations are more restricted. For example I
believe that:

(char*)0;
will be the null pointer constant if evaluated at compile time but

(char *)<expr>;

Is not if expr is a non-constant expression even if it evaluates to 0 at
runtime.


The proposal isn't to allow runtime implicit conversion but specifically
to allow compile time representation of the null pointer constant as
(void*)0;

Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

James...@dresdner-bank.com

unread,
Aug 17, 1999, 3:00:00 AM8/17/99
to

In article <pe1$bSAl09...@robinton.demon.co.uk>,

Francis Glassborow <fran...@robinton.demon.co.uk> wrote:
>
> In article <7p88pd$av7$1...@mulga.cs.mu.OZ.AU>, Fergus Henderson
> <f...@cs.mu.OZ.AU> writes
> >C++ did after all
> >adopt pretty much everything else in ANSI C. So I still consider
this
> >one to be a gratuitous difference from ANSI C.

> And one that we could correct?

No. It is a real change in what was consciously voted into the
standard. Obviously, I would prefer something different, since I was
the one who wrote up the proposal. But what the language needs now (and
IMHO, has needed for some time) is stability. And running around trying
to correct things because maybe the majority has changed is *not* a
means of acquiring that stability.

--
James Kanze mailto: James...@dresdner-bank.com

Conseils en informatique orientée objet/


Beratung in objekt orientierter Datenverarbeitung

Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Pete Becker

unread,
Aug 17, 1999, 3:00:00 AM8/17/99
to

Francis Glassborow wrote:
>
> In article <37B8C0E8...@acm.org>, Pete Becker <peteb...@acm.org>
> writes
> >No, I said "as few changes as possible," not "no changes." One of the
> >major goals of C++ was type safety, and a consequence of that is that a
> >pointer to void cannot be implicitly converted to a pointer to some
> >other type.
>
> Much as I respect your opinions, I have to add that neither can any
> integer type be converted implicitly to any pointer type. Yet both C
> and C++ make a specific exception for almost any compile time constant
> inter expression that evaluates to zero. However C++ does not extend
> this exception to (void*)0. I understand, and accept Bjarne's
> explanation that this was a change in C after C++ had already been
> designed, however we have other other more extensive changes to C++ over
> the last 10 years (i.e. since the release of C89). If a proposal for
> support for (void *)0 to be a null pointer constant in C++ was really
> made, I for one, would love to know the rationale for its rejection.
> Type safety just does not cut it.

I don't recall any such proposal, which isn't to say that there wasn't
any. I'm agnostic on the question whether there should be an implicitly
converting null pointer constant. I do try to keep distinct issues
distinct, however. Type safety dictates that there not be a general
conversion from void* to some other pointer type. That's why C's usual
definition of NULL doesn't work in C++, and it's also why assigning the
result of malloc to some other pointer type doesn't work in C++.
Changing the rules for the former doesn't require changing the rules for
the latter, and doesn't require abandoning type safety. But the loss of
NULL (if it was, indeed, a loss) is a consequence of the decision to
impose stronger type safety. Nobody decided that C's definition of NULL
shouldn't work, it just happened. Which is why I keep objecting to
statements about the non-existent 'change' in the definition of null
pointer constant.

Several years ago I read a list of "silly" laws. One of the laws was
described as prohibiting photographing a rabbit on October 14. Now, that
certainly sounds stupid. What the law actually said was that it was
illegal to photograph animals in the wild during hunting season. That's
not so stupid, although some may feel that its goals were misguided.
(There was a movement in the US prior to that to interfere with hunters
by going out into the woods, ostensibly to photograph wildlife, and make
so much ruckus that the animals would be driven away). Focusing on a
narrow example of the application of the law rather than the actual law
was misleading.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com

David R Tribble

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to

Bjarne Stroustrup wrote:
> At best (void*)0 as a special case would be yet another ugly wart. It
> might do the job, but I would expect everybody to hide that wart in
> a NULL macro.

A case could be made, in fact, that 'NULL' itself be considered a
special identifier/keyword meaning "null pointer constant". ('NULL'
is already a reserved identifier in both C and C++.) That would
remove the ugliness that comes with a typecast.

It would, however, pose the risk of breaking incorrect, or at lease
unportable, existing programs that take liberties in assuming that
'NULL' is an integer.

-- David R. Tribble, da...@tribble.com --

Francis Glassborow

unread,
Aug 18, 1999, 3:00:00 AM8/18/99
to

In article <7pbtec$2o8$1...@nnrp1.deja.com>, James...@dresdner-bank.com
writes

>No. It is a real change in what was consciously voted into the
>standard. Obviously, I would prefer something different, since I was
>the one who wrote up the proposal. But what the language needs now (and
>IMHO, has needed for some time) is stability. And running around trying
>to correct things because maybe the majority has changed is *not* a
>means of acquiring that stability.

An attitude with which I have no problem, note, please that at the
Dublin meeting I was one of the most vociferous opponents of responses
to DRs that proposed language extensions, however reasonable. However I
do not think we are actually changing the language. Even if C++ remains
exactly as it is I would still strongly encourage all implementors to
provide (void *)0 is a null pointer constant as an extension. I would
like to see a single uniform definition of this extension. It is within
our power to do such a thing (some of the changes introduced into C
through the five year amendments were much more substantial than this)

Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Douglas A. Gwyn

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
David R Tribble wrote:
> A case could be made, in fact, that 'NULL' itself be considered a
> special identifier/keyword meaning "null pointer constant". ('NULL'
> is already a reserved identifier in both C and C++.) That would
> remove the ugliness that comes with a typecast.

No, "NULL" is reserved in Standard C only if one of the headers
that defined it is included.

> It would, however, pose the risk of breaking incorrect, or at lease
> unportable, existing programs that take liberties in assuming that
> 'NULL' is an integer.

It would presumably cause problems for *careful, portable* code
that contains constructs like
#ifndef NULL
#define NULL 0
#endif
which would be overriding a builtin.
---

Max TenEyck Woodbury

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
David R Tribble wrote:
>...

>
> A case could be made, in fact, that 'NULL' itself be considered a
> special identifier/keyword meaning "null pointer constant". ('NULL'
> is already a reserved identifier in both C and C++.) That would
> remove the ugliness that comes with a typecast.

Are you sure of that? If I remember correctly, it is a macro that is
only defined if you include the appropriate header.

>...

mt...@cds.duke.edu

Fergus Henderson

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Pete Becker <peteb...@acm.org> writes:

>I'm agnostic on the question whether there should be an implicitly
>converting null pointer constant. I do try to keep distinct issues
>distinct, however. Type safety dictates that there not be a general
>conversion from void* to some other pointer type.

Agreed.

>That's why C's usual definition of NULL doesn't work in C++,

Here I disagree.

>and it's also why assigning the
>result of malloc to some other pointer type doesn't work in C++.

Agreed.

>Changing the rules for the former doesn't require changing the rules for
>the latter, and doesn't require abandoning type safety.

Right. So why do you say that reason why C's usual definition of NULL
(as `(void *)0') does not work in C++ is because type safety dictates that
there not be a general conversion from void* to some other pointer type?
As you say changing one doesn't require changing the other, so I don't
see the connection.

>But the loss of
>NULL (if it was, indeed, a loss) is a consequence of the decision to
>impose stronger type safety.

Again, I don't see why you say this.

>Nobody decided that C's definition of NULL shouldn't work, it just happened.

Originally, yes, it just happened, as C and C++ evolved and diverged.

Eventually however James Kanze wrote a formal proposal to allow C's
definition of NULL to work in C++, but the C++ committee (or at least
the working group which examined that proposal) decided to reject it.
So in fact an explicit decision was made. For that reason, I agree
with James Kanze that Francis's suggestion that this could be fixed
by defect report is not a good idea.

>Which is why I keep objecting to statements about the non-existent
>'change' in the definition of null pointer constant.

This is a legitimate objection. I apologize for originally characterizing
the issue in misleading terms.

--
Fergus Henderson <f...@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 f...@128.250.37.3 | -- the last words of T. S. Garp.

Jeff Rife

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Douglas A. Gwyn (gw...@arl.mil) wrote:

> > It would, however, pose the risk of breaking incorrect, or at lease
> > unportable, existing programs that take liberties in assuming that
> > 'NULL' is an integer.
>
> It would presumably cause problems for *careful, portable* code
> that contains constructs like
> #ifndef NULL
> #define NULL 0
> #endif
> which would be overriding a builtin.

But, if the standard changed what NULL was, then this *careful, portable*
code you use would no longer be conforming.

That's because your *careful, portable* code is neither, unless it
appears in the implementation-supplied header files.

Re-defining anything the standard says that the implementation should
define always leads to undefined behavior. In this case, you are not
going to cause problems with real-world compilers, with the current
standard, but it is still not a good thing to do.

--
Jeff Rife | "Only one human captain has ever survived battle
19445 Saint Johnsbury Lane | with a Minbari fleet...he is behind me...you are
Germantown, MD 20876-1610 | in front of me. If you value your lives,
Home: 301-916-8131 | be somewhere else."
Work: 301-770-5800 Ext 5335 | -- Ambassador Delenn, 2260

James...@dresdner-bank.com

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
In article <37B9E0C4...@tribble.com>,

David R Tribble <da...@tribble.com> wrote:
>
> Bjarne Stroustrup wrote:
> > At best (void*)0 as a special case would be yet another ugly wart.
It
> > might do the job, but I would expect everybody to hide that wart in
> > a NULL macro.
>
> A case could be made, in fact, that 'NULL' itself be considered a
> special identifier/keyword meaning "null pointer constant". ('NULL'
> is already a reserved identifier in both C and C++.) That would
> remove the ugliness that comes with a typecast.
>
> It would, however, pose the risk of breaking incorrect, or at lease
> unportable, existing programs that take liberties in assuming that
> 'NULL' is an integer.

The solution should definitly not be to change the macro status of NULL,
or the fact that it is defined in a header. If the special keyword
route is chosen, then the keyword should be something like __null, and
the macro NULL should be required to be defined to the keyword.

If this route is taken, we must be careful to define what happens in
cases like:

template< typename T >
void
f( T p )
{
cout << typeid( p ).name() << '\n' ;
}

f( NULL ) ;

--
James Kanze mailto: James...@dresdner-bank.com
Conseils en informatique orientée objet/
Beratung in objekt orientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Greg Brewer

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
> Agreed. The proposal was rejected. It's not the only proposal that was
> rejected -- either I didn't argue my point well enough, or it really
> isn't as important as I thought. At any rate, I accept the committees
> decision.

Well, I don't. I want names and addresses. "Bruno, get ready to take a
trip."


Just a little levity to lighten the discussion. :-)

David R Tribble

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to

"Douglas A. Gwyn" wrote:

>
> David R Tribble wrote:
> > A case could be made, in fact, that 'NULL' itself be considered a
> > special identifier/keyword meaning "null pointer constant". ('NULL'
> > is already a reserved identifier in both C and C++.) That would
> > remove the ugliness that comes with a typecast.
>
> No, "NULL" is reserved in Standard C only if one of the headers
> that defined it is included.
>
> > It would, however, pose the risk of breaking incorrect, or at lease
> > unportable, existing programs that take liberties in assuming that
> > 'NULL' is an integer.
>
> It would presumably cause problems for *careful, portable* code
> that contains constructs like
> #ifndef NULL
> #define NULL 0
> #endif
> which would be overriding a builtin.

Unless, of course, <stddef.h> contained:

#define NULL NULL

-- David R. Tribble, da...@tribble.com --

Douglas A. Gwyn

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to

Jeff Rife wrote:
> Douglas A. Gwyn (gw...@arl.mil) wrote:
> > #ifndef NULL
> > #define NULL 0
> > #endif
> > which would be overriding a builtin.
> But, if the standard changed what NULL was, then this *careful, portable*
> code you use would no longer be conforming.

Isn't that the problem I identified with making such a change?
As it stands now, NULL is a macro that is defined only under
certain circumstances, and the above is strictly conforming.

It isn't a *redefinition*, it's providing a definition when
the implementation hasn't already done so.

If you haven't had to use a similar construct, then either
you don't use "NULL", or you haven't ported much code.

Douglas A. Gwyn

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to

Okay, I feel I have to chime in on this matter of C++
NULL and "type safety". The very idea that an unadorned
"0" could be considered automatically interconvertable
with a pointer to any type is in itself contrary to type
safety. It could be type-safely supported in the form
of a cast, e.g. (int*)0, but e.g.
int *pi = ...;
if ( pi == 0 ) ...
ought to be a type violation, in a type-safe language.

The right answer, of course, is that there should be a
typeless keyword, perhaps "nil", as in other languages.

Jeff Rife

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to

Douglas A. Gwyn (gw...@arl.mil) wrote:

> Isn't that the problem I identified with making such a change?
> As it stands now, NULL is a macro that is defined only under
> certain circumstances,

True. This is one of the problems. It would be better if an
implementation made NULL one of those "magic" defines, like
__cplusplus, that don't really get #defined in any file, but stille
exist.

> and the above is strictly conforming.

Well, not really.

An implementation can be conforming by doing:

const int _foo = 0;
const int _bar = 0;
#define NULL (_foo + _bar)

The implementation uses the (_foo + _bar) token stream as a indicator
that this is a null pointer constant. This is completely legal by
the standard.

Now, if you forget to include the header that defines this (rather
strange, I'll admit) NULL macro, and use your code, then the indicator
property is lost, and the compilation might fail.

> It isn't a *redefinition*, it's providing a definition when
> the implementation hasn't already done so.

But it may not be the "right" definition. It fits the text of the
standard, but an implementation doesn't have to do it exactly that
way.

If the implementation doesn't define NULL in the right place, then it
is not conforming, so your definition doesn't really matter. An integer
constant 0 isn't a null-pointer constant in such an implementation.

If an implementation defines NULL in the right place, and you don't
include that file, and define NULL on your own, your code is non-standard,
and the oft-referenced hard drive formatting could take place.

If an implementation defines NULL in the right place, and you include
that file, and define NULL on your own, your code is non-standard.

If an implementation defines NULL in the right place, and you include
that file, and define NULL on your own, with that guard #ifndef, your
code is standard, and should be fine.

--
Jeff Rife | "If the world were destroyed and you were the
19445 Saint Johnsbury Lane | last man within a thousand mile radius, I would
Germantown, MD 20876-1610 | swim across the ocean on a rumor that Screech
Home: 301-916-8131 | from 'Saved by the Bell' was spotted in Japan."
Work: 301-770-5800 Ext 5335 | -- Ellen

Paul Jarc

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to

Jeff Rife <jrif...@BEnabsGONE.net> writes:
> An implementation can be conforming by doing:
>
> const int _foo = 0;
> const int _bar = 0;
> #define NULL (_foo + _bar)

That works in C++, but not C. (But enums work in C - close enough.)

> Now, if you forget to include the header that defines this (rather
> strange, I'll admit) NULL macro, and use your code, then the indicator
> property is lost, and the compilation might fail.

No, `0' still must be accepted as a null pointer constant, even if
NULL is #defined differently, and even if the expansion of NULL is
treated magically. Warnings are allowed, as always, but this cannot
cause translation to fail. (This might be different for C++, but I
doubt it.)

> Douglas A. Gwyn (gw...@arl.mil) wrote:
> > It isn't a *redefinition*, it's providing a definition when
> > the implementation hasn't already done so.

C9X 7.1.3p2:
# If the program ... defines a reserved identifier as a macro name,
# the behavior is undefined.

So it depends on whether the identifier is reserved, not just whether
it's currently defined.

7.1.3p1:
# Each macro name in any of the following subclauses ... is reserved
# for use as specified if any of its associated headers is
# included....

So you'd have to watch out for #inclusions of the standard headers
that occur after your definition. If that happens, your code becomes
non-strictly-conforming.


paul

Pete Becker

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to
Fergus Henderson wrote:
>
> Pete Becker <peteb...@acm.org> writes:
>
> >I'm agnostic on the question whether there should be an implicitly
> >converting null pointer constant. I do try to keep distinct issues
> >distinct, however. Type safety dictates that there not be a general
> >conversion from void* to some other pointer type.
>
> Agreed.
>
> >That's why C's usual definition of NULL doesn't work in C++,
>
> Here I disagree.
>
> >and it's also why assigning the
> >result of malloc to some other pointer type doesn't work in C++.
>
> Agreed.
>
> >Changing the rules for the former doesn't require changing the rules for
> >the latter, and doesn't require abandoning type safety.
>
> Right. So why do you say that reason why C's usual definition of NULL
> (as `(void *)0') does not work in C++ is because type safety dictates that
> there not be a general conversion from void* to some other pointer type?

No, it's because C++ does not have a general conversion from void* to
some other pointer type.

> As you say changing one doesn't require changing the other, so I don't


> see the connection.
>
> >But the loss of
> >NULL (if it was, indeed, a loss) is a consequence of the decision to
> >impose stronger type safety.
>
> Again, I don't see why you say this.

Because that's what happened.

>
> >Nobody decided that C's definition of NULL shouldn't work, it just happened.
>
> Originally, yes, it just happened, as C and C++ evolved and diverged.

Exactly.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com

---

Valentin Bonnard

unread,
Aug 23, 1999, 3:00:00 AM8/23/99
to

You are both right:

Fergus: U doesn't work because of V doesn't either
Pete: U doesn't work because of W doesn't either

Any of {V,W} would make U valid. There is no
point in trying to decide if V is more guilty
than W.

Valentin: U doesn't work because both V and W
don't work.

--

Valentin Bonnard

Clive D.W. Feather

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to

In article <MPG.12278d84...@news.nabs.net>, Jeff Rife

<jrif...@BEnabsGONE.net> writes
>An implementation can be conforming by doing:
>
>const int _foo = 0;
>const int _bar = 0;
>#define NULL (_foo + _bar)

Actually it can't, because that isn't a constant expression with value 0
(in C; I believe C++ has different rules here).

Change it to:

enum { __janet, _john };
#define NULL ( _janet & _john }

and you're okay.

--
Clive D.W. Feather | Internet Expert | Work: <cl...@demon.net>
Tel: +44 20 8371 1138 | Demon Internet Ltd. | Home: <cl...@davros.org>
Fax: +44 20 8371 1037 | | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address

0 new messages