Topic: null pointers (was: Why's of C++ -- Part 1)


Author: David R Tribble <david@tribble.com>
Date: 1999/08/31
Raw View
Andrew Koenig wrote:
>> Therefore, good programming practice would be to call f((char *) 0)
>> anyway.  In which case the whole null-pointer debate becomes moot.

David R Tribble <david@tribble.com> wrote:
>> No, good programming practice would be to call 'f((char *)NULL)',
>> and to disallow using NULL as an integer constant.

Andrew Koenig wrote:
> Why good?  It seems like needless churn to me.

Let me reiterate/rephrase for emphasis:

 Good programming practice would be to call f((char*)NULL),
 and to disallow using NULL as an integer constant,
 and to disallow using 0 as anything other than an integer constant.

Why do some people object so strongly to preferring NULL over 0?
IMHO, using 0 for null seems to be nothing more than an opportunity
to create needless confusion.

-- David R. Tribble, david@tribble.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <david@tribble.com>
Date: 1999/08/26
Raw View
David R Tribble  <david@tribble.com> wrote:
> >Pete Becker wrote:
>
> >> > I agree with you on you last point but how would you feel about a
> >> > proposal that would make calling
> >> >     void f(char *);
> >> >     void f(int);
> >> > with
> >> >      f(NULL);
> >> > and
> >> >      f(0);
> >> > no longer ambiguous?
>
> >> They are not currently ambiguous. Both call f(int).
>
>> Exactly; this is part of the whole "C++ null problem".
>
>> There have been suggestions that if 'NULL' is defined as
>> '((void*)0)', then the calls above would not be ambiguous, and
>> 'f(NULL)' calls 'f(char*)'.
>>
>> The drawback to such a suggestion is that it would break code that
>> assumes 'NULL' is an integer.  Which is no great loss, in my opinion.

Andrew Koenig wrote:
> There is a more important drawback:  If we were now to add
>
>         void f(int *);
>
> then f(NULL) would become ambiguous again.

Which is acceptable; at least it's an ambiguous *pointer* type.

> Therefore, good programming practice would be to call f((char *) 0)
> anyway.  In which case the whole null-pointer debate becomes moot.

No, good programming practice would be to call 'f((char *)NULL)',
and to disallow using NULL as an integer constant.

-- David R. Tribble, david@tribble.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ark@research.att.com (Andrew Koenig)
Date: 1999/08/27
Raw View
In article <37C4675F.C5B69AE9@tribble.com>,
David R Tribble  <david@tribble.com> wrote:

>> Therefore, good programming practice would be to call f((char *) 0)
>> anyway.  In which case the whole null-pointer debate becomes moot.

>No, good programming practice would be to call 'f((char *)NULL)',
>and to disallow using NULL as an integer constant.

Why good?  It seems like needless churn to me.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 1999/08/25
Raw View
James.Kanze@dresdner-bank.com wrote:
>
> clamage@eng.sun.com (Steve Clamage) wrote:
>> If C++ had a keyword for null pointer, this particular problem
>> would go away. But you would still need disambiguation when a
>> function was overloaded on different pointer types.
>
> Precisely.  IMHO, this is the best solution, since for a real, logical
> null pointer, there is no reason to prefer a function taking a void*.
>
> Another advantage of a real null pointer type is that it can be made
> illegal to pass it to a var_arg.
>
> The main disadvantage is that it would take a lot of work to specify
> it adequately, and I haven't seen any volunteers :-).

See my http://david.tribble.com/text/c9xnull.txt .

Just ignore the parts specific to C.  The actual changes needed to
the ISO C++ document would be far less verbiage than what I wrote;
I was merely trying to cover all the relevant areas.

-- David R. Tribble, david@tribble.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Paul Black <paul@canix.co.uk>
Date: 1999/08/25
Raw View
"Bill Wade" <bill.wade@stoner.com> wrote:
> (char*)0 is not the null pointer constant.  Rather it is a char* which has
> the value null.  Representation is an implementation concern.

"null pointer value" is the description applied to the result.

Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Greg Brewer" <nospam.greg@brewer.net>
Date: 1999/08/25
Raw View
Andrew Koenig <ark@research.att.com> wrote in message
news:FH14Lt.HIn@research.att.com...
> In article <37C1B627.F6402796@tribble.com>,
> David R Tribble  <david@tribble.com> wrote:
> >Pete Becker wrote:
> There is a more important drawback:  If we were now to add
> void f(int *);
> then f(NULL) would become ambiguous again.
> Therefore, good programming practice would be to call f((char *) 0)
> anyway.  In which case the whole null-pointer debate becomes moot.

I thought someone might call attention to the possibility.  Since C -- which
is the foundation for C++ -- does not have a string data type, char * and
const char * are used as basic data types.  In my case, I am trying to
create an object that can be initialized with data in a variable of formats.
In the case that spawned this thread, the constructor was overload 4 times:
six ints, one long, one string, or two strings.  I had to eliminate the one
string constructor because it considered and single argument of (0) as
ambiguous between the one string version and the one long version.

My primary concern has been that using zero as an argument to an overloaded
function was ambiguous if there was any version of the function with a
pointer as the argument.  I do think the arguments are just as valid when
NULL is used as an argument.

Does anyone speaking against any change remember being new to C++?  Don't
you remember writing an overloaded function and puzzling over an ambiguity
error message that didn't make sense?
    foo("prime numbers");
    foo(7);
    foo(5);
    foo(3);
    foo(2);
    foo(1);
    foo(0); // error, ambigous?????
    foo(-1);

I had something like the above.  I was stumped for a long time.  It's a
situation I think should be corrected.

Greg Brewer





[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Salters <salters@lucent.com>
Date: 1999/08/24
Raw View
Francis Glassborow wrote:

> In article <37C16C7E.3C05BBA2@lucent.com>, Salters <salters@lucent.com>
> writes
> >Brute force - f( (char *)( (void *)0 ) )?
                             ^^^^^^^^^
> In C++ this not a null pointer constant.  Yes I know it usually works
> but this is comp.std.c++.  I think the only way we have of passing a
> null pointer to a function in the presence of an overload set that
> includes a function that can take an int is something like:

Now I am getting confused - I thought "0" is a null pointer constant in
contexts where a pointer is required, so (void*)0 would be an (rvalue)
null pointer. This can then be converted to the appropriate pointer
type with yet another cast, which should keep the null pointer property.

If not a null pointer, nor a null pointer constant, then what is (the type
of) (void*) 0 ?

Michiel Salters


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: stanley@West.Sun.COM (Stanley Friesen [Contractor])
Date: 1999/08/24
Raw View
In article <2yG4gOAhsRv3EwJN@robinton.demon.co.uk>,
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
>A further problem has just occurred to me.  Given an overload set
>including f(int) and f(char *) how do I pass the value of the null
>pointer constant to the second one?
>
>f(0) resolves in a call to f(int)
>f((void *)0) falls foul of there being no conversion

It succeeds because, being the null pointer constant, it is magic, and
can be converted into any object pointer type implicitly.

That is, we are suggesting a *change* to the standard to make the above
sequence a magic sequence by officially declaring any constant expression
evauating to zero and cast to "void *" to be an instance of the null pointer
constant.
>
>It seems to me that C++ provides no standard conforming mechanism to
>pass a null pointer constant to f(char *) in the presence of any version
>of f that can take an integer type argument.

Yes, that is correct.  That is *why* this change ot the standard has been
suggested.  Many of us find the idea of a null pointer constant that prefers
int parameters over pointer ones to be counter-intuitive, and want this
fixed in the next version of C++.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/08/24
Raw View
In article <7prvof$mj7$1@engnews1.eng.sun.com>,
  clamage@eng.sun.com (Steve Clamage) wrote:
>
> Francis Glassborow <francis@robinton.demon.co.uk> writes:
>
> >In article <7phdj7$4oj@abyss.West.Sun.COM>, Stanley Friesen
[Contractor]
> ><stanley@West.Sun.COM> writes

> >>The example I was actually objecting to was using a *variable* of
> >>type int that happened to have the value zero.  THAT I find
> >>unacceptable. And it is certainly not allowed in C, so there is no
> >>reason from compatibility to accept it in C++.

> >A further problem has just occurred to me.  Given an overload set
> >including f(int) and f(char *) how do I pass the value of the null
> >pointer constant to the second one?

> >f(0) resolves in a call to f(int)
> >f((void *)0) falls foul of there being no conversion
> >f((char *)0) may seem correct but it is not the null pointer constant
> >and can be coded differently (and, I believe, actually is on some
> >debugging implementations).

> You don't need to pass a "null pointer constant" to a function.  You
> pass a null pointer. The term "null pointer constant" is a source-code
> concept. It gets converted to a typed null pointer rvalue.

> If your choice of overloading causes problems, you need to introduce
> auxiliary constructs.

> If C++ had a keyword for null pointer, this particular problem
> would go away. But you would still need disambiguation when a function
> was overloaded on different pointer types.

Precisely.  IMHO, this is the best solution, since for a real, logical
null pointer, there is no reason to prefer a function taking a void*.

Another advantage of a real null pointer type is that it can be made
illegal to pass it to a var_arg.

The main disadvantage is that it would take a lot of work to specify it
adequately, and I haven't seen any volenteers:-).

--
James Kanze                   mailto: James.Kanze@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.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/24
Raw View
In article <37C15258.8C236E32@wizard.net>, James Russell Kuyper Jr.
<kuyper@wizard.net> writes
>However, it must compare equal to the null pointer constant (after
>suitable conversions). Code that does anything with it other than
>checking it for equality (after suitable conversions) is in trouble
>anyway.

Why?  Has C++ provided some special way round this? We have been round
this loop many times in C.


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
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1999/08/24
Raw View
Francis Glassborow wrote:
>
> In article <37C16C7E.3C05BBA2@lucent.com>, Salters <salters@lucent.com>
> writes
> >Brute force - f( (char *)( (void *)0 ) )?
>                              ^^^^^^^^^
> In C++ this not a null pointer constant.  Yes I know it usually works

No, but the '0' is. What you have is a series of casts that should leave
us with a null pointer of type 'char *'.

> but this is comp.std.c++.  I think the only way we have of passing a
> null pointer to a function in the presence of an overload set that
> includes a function that can take an int is something like:
>
> char * argument=0;
> f(argument);

Why can't you use '(char *)0'?
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Lisa Lippincott <lisa_lippincott@advisories.com>
Date: 1999/08/24
Raw View
Salters <salters@lucent.com> asks:
> If not a null pointer, nor a null pointer constant, then what is
? (the type of) (void*) 0 ?

(void *)0 is a null pointer; it has type void *; but (in C++) it is not a
null pointer constant -- null pointer constants have integral type.

I think the confusion here arises from the subtlety of the C-style cast.
This cast is a static_cast, which will convert null pointer constants to
null pointers.

On the other hand, since (0,0) is not a null pointer constant (it's not
a constant expression), the similar-looking cast (void *)(0,0) is a
reinterpret_cast, and need not produce a null pointer.

                                                   --Lisa Lippincott
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1999/08/24
Raw View
Francis Glassborow wrote in message
<2yG4gOAhsRv3EwJN@robinton.demon.co.uk>...

>A further problem has just occurred to me.  Given an overload set
>including f(int) and f(char *) how do I pass the value of the null
>pointer constant to the second one?


Passing the value of the null pointer to the second one means passing a null
char* to the second one.

>f((char *)0) may seem correct but it is not the null pointer constant
>and can be coded differently (and, I believe, actually is on some
>debugging implementations).


(char*)0 is not the null pointer constant.  Rather it is a char* which has
the value null.  Representation is an implementation concern.

(char*)0 means the same thing as
  static_cast<char*>(0);
and that means the same thing as
  char* t(0);
  t;
for some invented variable t.

If the interpretation were
   int i = 0;    // Not a compile-time constant
  (char*) i;
The cast would be a reinterpret cast and might do the wrong thing.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <david@tribble.com>
Date: 1999/08/24
Raw View
Pete Becker wrote:
>
> Greg Brewer wrote:
> >
> > I agree with you on you last point but how would you feel about a
> > proposal that would make calling
> >     void f(char *);
> >     void f(int);
> > with
> >      f(NULL);
> > and
> >      f(0);
> > no longer ambiguous?
>
> They are not currently ambiguous. Both call f(int).

Exactly; this is part of the whole "C++ null problem".

There have been suggestions that if 'NULL' is defined as '((void*)0)',
then the calls above would not be ambiguous, and 'f(NULL)' calls
'f(char*)'.

The drawback to such a suggestion is that it would break code that
assumes 'NULL' is an integer.  Which is no great loss, in my opinion.

-- David R. Tribble, david@tribble.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/08/24
Raw View
In article <37C16C7E.3C05BBA2@lucent.com>,
  Salters <salters@lucent.com> wrote:
>
> Francis Glassborow wrote:

> > A further problem has just occurred to me.  Given an overload set
> > including f(int) and f(char *) how do I pass the value of the null
> > pointer constant to the second one?

> > f(0) resolves in a call to f(int)
> > f((void *)0) falls foul of there being no conversion
> > f((char *)0) may seem correct but it is not the null pointer
constant
> > and can be coded differently (and, I believe, actually is on some
> > debugging implementations).

> > It seems to me that C++ provides no standard conforming mechanism to
> > pass a null pointer constant to f(char *) in the presence of any
version
> > of f that can take an integer type argument.

> > I know it usually works in practice, but that is not the point.  If
I am
> > right, there is a defect in the Standard.

> Brute force - f( (char *)( (void *)0 ) )?

Not necessary.  f( (char*)0 ) works perfectly well (guaranteed by the
standard).  0 is a null pointer constant, and converting it to a pointer
must result in a null pointer.

> This must be a pointer to a char, initialized by a null pointer.
> Parsing:
> char * (              ) // create temporary of type char *
>          (void *) 0 )   // with this null pointer.
>
> The problem I fear is the "value of the null pointer constant".
> I'm not sure if the standard actually defines such a thing, the
> only requirement on null pointers being that they compare equal.

Correct.  The "null pointer constant" is a syntactical construct.  There
is, for example, no requirement that the representation of a char* null
pointer be the same as that of an int* null pointer.

--
James Kanze                   mailto: James.Kanze@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.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Salters <salters@lucent.com>
Date: 1999/08/23
Raw View
Francis Glassborow wrote:

> A further problem has just occurred to me.  Given an overload set
> including f(int) and f(char *) how do I pass the value of the null
> pointer constant to the second one?

> f(0) resolves in a call to f(int)
> f((void *)0) falls foul of there being no conversion
> f((char *)0) may seem correct but it is not the null pointer constant
> and can be coded differently (and, I believe, actually is on some
> debugging implementations).

> It seems to me that C++ provides no standard conforming mechanism to
> pass a null pointer constant to f(char *) in the presence of any version
> of f that can take an integer type argument.

> I know it usually works in practice, but that is not the point.  If I am
> right, there is a defect in the Standard.

Brute force - f( (char *)( (void *)0 ) )?

This must be a pointer to a char, initialized by a null pointer.
Parsing:
char * (              ) // create temporary of type char *
         (void *) 0 )   // with this null pointer.

The problem I fear is the "value of the null pointer constant".
I'm not sure if the standard actually defines such a thing, the
only requirement on null pointers being that they compare equal.

Michiel Salters


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: 1999/08/23
Raw View
Francis Glassborow wrote:
....
> A further problem has just occurred to me.  Given an overload set
> including f(int) and f(char *) how do I pass the value of the null
> pointer constant to the second one?
>
> f(0) resolves in a call to f(int)
> f((void *)0) falls foul of there being no conversion
> f((char *)0) may seem correct but it is not the null pointer constant
> and can be coded differently (and, I believe, actually is on some
> debugging implementations).

However, it must compare equal to the null pointer constant (after
suitable conversions). Code that does anything with it other than
checking it for equality (after suitable conversions) is in trouble
anyway.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/08/23
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> writes:

>In article <7phdj7$4oj@abyss.West.Sun.COM>, Stanley Friesen [Contractor]
><stanley@West.Sun.COM> writes
>>The example I was actually objecting to was using a *variable* of type int
>>that happened to have the value zero.  THAT I find unacceptable.  And it is
>>certainly not allowed in C, so there is no reason from compatibility to
>>accept it in C++.

>A further problem has just occurred to me.  Given an overload set
>including f(int) and f(char *) how do I pass the value of the null
>pointer constant to the second one?

>f(0) resolves in a call to f(int)
>f((void *)0) falls foul of there being no conversion
>f((char *)0) may seem correct but it is not the null pointer constant
>and can be coded differently (and, I believe, actually is on some
>debugging implementations).

You don't need to pass a "null pointer constant" to a function.
You pass a null pointer. The term "null pointer constant" is a
source-code concept. It gets converted to a typed null pointer rvalue.

If your choice of overloading causes problems, you need to introduce
auxiliary constructs.

If C++ had a keyword for null pointer, this particular problem
would go away. But you would still need disambiguation when a function
was overloaded on different pointer types.

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


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/23
Raw View
In article <37C16C7E.3C05BBA2@lucent.com>, Salters <salters@lucent.com>
writes
>Brute force - f( (char *)( (void *)0 ) )?
                             ^^^^^^^^^
In C++ this not a null pointer constant.  Yes I know it usually works
but this is comp.std.c++.  I think the only way we have of passing a
null pointer to a function in the presence of an overload set that
includes a function that can take an int is something like:

char * argument=0;
f(argument);

I think that shows that there is something wrong.  We need (void*)0 as a
null pointer constant to disambiguate overloaded functions.

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


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jeff Rife <jrifeSPAM@BEnabsGONE.net>
Date: 1999/08/23
Raw View
Francis Glassborow (francis@robinton.demon.co.uk) wrote:

> It seems to me that C++ provides no standard conforming mechanism to
> pass a null pointer constant to f(char *) in the presence of any version
> of f that can take an integer type argument.
>
> I know it usually works in practice, but that is not the point.  If I am
> right, there is a defect in the Standard.

Finally, something concrete we can take back to the committee without
having to *add* a feature to the standard!

I was leaning towards this sort of thing myself, and I still think it
comes down to the fact that strong typing says that integers are
not pointers (and vice versa), yet in the case of the null pointer,
*it is an integer*, and that is what is wrong with the definition.

--
Jeff Rife                   | "Don't try this at home, kids.  This should
19445 Saint Johnsbury Lane  |  be done only by trained professional idiots."
Germantown, MD  20876-1610  |
Home: 301-916-8131          |              -- Plucky Duck, "Hollywood Plucky"
Work: 301-770-5800 Ext 5335 |
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/08/23
Raw View
In article <2yG4gOAhsRv3EwJN@robinton.demon.co.uk>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
> In article <7phdj7$4oj@abyss.West.Sun.COM>, Stanley Friesen
[Contractor]
> <stanley@West.Sun.COM> writes
> >The example I was actually objecting to was using a *variable* of
> >type int that happened to have the value zero.  THAT I find
> >unacceptable.  And it is certainly not allowed in C, so there is no
> >reason from compatibility to accept it in C++.

> A further problem has just occurred to me.  Given an overload set
> including f(int) and f(char *) how do I pass the value of the null
> pointer constant to the second one?

You don't, of course.  Any more than you pass any other literal to a
function in general.  A value is passed to the function, but whether
that value is the result of a literal or not, there is no way for the
function to tell.

You can, of course, pass a null pointer to the function.

> f(0) resolves in a call to f(int)
> f((void *)0) falls foul of there being no conversion
> f((char *)0) may seem correct but it is not the null pointer constant
> and can be coded differently (and, I believe, actually is on some
> debugging implementations).

When you say "coded differently", what do you mean.  The expression
"(char*)0" is a null pointer, and must be coded as such.

> It seems to me that C++ provides no standard conforming mechanism to
> pass a null pointer constant to f(char *) in the presence of any
> version of f that can take an integer type argument.

A null pointer constant is a compile time construct, and has no meaning
at run time.  You can pass a null pointer to the function, and that is
all that counts.

--
James Kanze                   mailto: James.Kanze@dresdner-bank.com
Conseils en informatique orient=E9e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh=FCttenweg 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.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <david@tribble.com>
Date: 1999/08/23
Raw View
Francis Glassborow wrote:
>
> Greg Brewer <nospam.gregb@hal-pc.org> writes
> > If the rules define f(int) as the correct choice when resolving
> > f(NULL)
>
> The compiler never sees f(NULL) by the time it sees your code the pre-
> processor has made a textual substitution.  If you want to fix this
> problem, the null pointer constant has to be identified and tokenised
> early enough that the pre-processor cannot destroy the evidence.

Not necessarily.  An implementation could do this:

    // <cstddef>
    #pragma enable NULL
    #define NULL  NULL
    // from this point on, 'NULL' is a special keyword (and a macro)

And there are compilers (EDG) that do something similar already:

    #define NULL  __null

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


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/23
Raw View
In article <7phdj7$4oj@abyss.West.Sun.COM>, Stanley Friesen [Contractor]
<stanley@West.Sun.COM> writes
>The example I was actually objecting to was using a *variable* of type int
>that happened to have the value zero.  THAT I find unacceptable.  And it is
>certainly not allowed in C, so there is no reason from compatibility to
>accept it in C++.

A further problem has just occurred to me.  Given an overload set
including f(int) and f(char *) how do I pass the value of the null
pointer constant to the second one?

f(0) resolves in a call to f(int)
f((void *)0) falls foul of there being no conversion
f((char *)0) may seem correct but it is not the null pointer constant
and can be coded differently (and, I believe, actually is on some
debugging implementations).

It seems to me that C++ provides no standard conforming mechanism to
pass a null pointer constant to f(char *) in the presence of any version
of f that can take an integer type argument.

I know it usually works in practice, but that is not the point.  If I am
right, there is a defect in the Standard.



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
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: stanley@West.Sun.COM (Stanley Friesen [Contractor])
Date: 1999/08/19
Raw View
In article <7pdh80$qaf$1@engnews1.eng.sun.com>,
Steve Clamage <clamage@eng.sun.com> wrote:
>But there is utility in accepting the same null pointer constants
>that C accepts.
>
>In C, any constant integer expression with value 0, or that value
>cast to void*, is a null pointer constant. I don't see the benefit
>in accepting (void*)0 but rejecting, for example, ((void*)0L).

I can accept that.  Any integral constant expression cast to 'void *'
is a null pointer constant.

The example I was actually objecting to was using a *variable* of type int
that happened to have the value zero.  THAT I find unacceptable.  And it is
certainly not allowed in C, so there is no reason from compatibility to
accept it in C++.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Greg Brewer" <nospam.gregb@hal-pc.org>
Date: 1999/08/19
Raw View
Pete Becker <petebecker@acm.org> wrote in message
news:37BC4AC8.EDB45FDF@acm.org...
> > > > that would make calling
> > > >   void f(char *);
> > > >   void f(int);
> > > > with
> > > >    f(NULL);
> > > > and
> > > >    f(0);
> > > > no longer abiguous?
> > > They are not currently ambiguous. Both call f(int).
> >
> > Not according to Borland C++ 5.01.  Which is preferable to in the case
of
> > f(NULL).
> >
> If you want to do compiler polls, Borland C++ 5.3 doesn't complain about
> ambiguity. Neither does VC++ 5.0 nor VC++ 6.0, nor gcc (egcs-1.1.2), nor
> the Edison Design Group compiler. gcc resolves f(NULL) to f(void*)
> because of its definition of NULL as __null. All the others resolve
> f(NULL) to f(int), and all five compilers resolve f(0) to f(int).

I could really care less about what a half dozen compilers do when I don't
use them.  I would consider Borland C++ 5.01 to be an authoritative source
and all I was doing was quoting one.  If the source is wrong -- and it
appears that it is -- no big deal.

> But more to the point is that the language definition says that these
> calls are not ambiguous. 0 as a null pointer constant can be converted
> to a null pointer in order to call f(char*), but as an int it needs no
> conversion in order to call f(int), so f(int) is the correct choice.

If the rules define f(int) as the correct choice when resolving f(NULL) then
there is a problem with the rules.  Personally, I prefer an ambiguity error
to quietly calling a function other than the one I intended.

Greg Brewer


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxx
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/20
Raw View
In article <7phv5u$2fal$1@news.hal-pc.org>, Greg Brewer
<nospam.gregb@hal-pc.org> writes
>If the rules define f(int) as the correct choice when resolving f(NULL)

The compiler never sees f(NULL) by the time it sees your code the pre-
processor has made a textual substitution.  If you want to fix this
problem, the null pointer constant has to be identified and tokenised
early enough that the pre-processor cannot destroy the evidence.

> then
>there is a problem with the rules.  Personally, I prefer an ambiguity error
>to quietly calling a function other than the one I intended.

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


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/08/20
Raw View
Greg Brewer wrote:
...
> use them.  I would consider Borland C++ 5.01 to be an authoritative source
> and all I was doing was quoting one.  If the source is wrong -- and it
> appears that it is -- no big deal.

The only truly authoritative source is the standard. I'd recommend
getting a copy; they're fairly cheap. Look in the FAQ (see below) for
details.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/08/19
Raw View
stanley@West.Sun.COM (Stanley Friesen [Contractor]) writes:

>The special case would be exactly and only the token sequence "(void *)0".
>There is no reason to extend it to integers that happen to have the value
>zero.  That is not particularly useful.

But there is utility in accepting the same null pointer constants
that C accepts.

In C, any constant integer expression with value 0, or that value
cast to void*, is a null pointer constant. I don't see the benefit
in accepting (void*)0 but rejecting, for example, ((void*)0L).

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Pete Becker <petebecker@acm.org>
Date: 1999/08/19
Raw View
Greg Brewer wrote:
>
> I agree with you on you last point but how would you feel about a proposal
> that would make calling
>   void f(char *);
>   void f(int);
> with
>    f(NULL);
> and
>    f(0);
> no longer abiguous?
>

They are not currently ambiguous. Both call f(int).

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: miker3@ix.netcom.com (Michael Rubenstein)
Date: 1999/08/19
Raw View
On 19 Aug 99 08:21:23 GMT, Pete Becker <petebecker@acm.org>
wrote:

>Greg Brewer wrote:
>>
>> I agree with you on you last point but how would you feel about a proposal
>> that would make calling
>>   void f(char *);
>>   void f(int);
>> with
>>    f(NULL);
>> and
>>    f(0);
>> no longer abiguous?
>>
>
>They are not currently ambiguous. Both call f(int).

Am I missing something?  What if NULL is defined as 0L?
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Greg Brewer" <nospam.gregb@hal-pc.org>
Date: 1999/08/19
Raw View

Pete Becker <petebecker@acm.org> wrote in message
news:37BB6D8B.ADD24984@acm.org...
> > I agree with you on you last point but how would you feel about a
proposal
> > that would make calling
> >   void f(char *);
> >   void f(int);
> > with
> >    f(NULL);
> > and
> >    f(0);
> > no longer abiguous?
> They are not currently ambiguous. Both call f(int).


Not according to Borland C++ 5.01.  Which is preferable to in the case of
f(NULL).

Greg Brewer



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Pete Becker <petebecker@acm.org>
Date: 1999/08/19
Raw View
Michael Rubenstein wrote:
>
> On 19 Aug 99 08:21:23 GMT, Pete Becker <petebecker@acm.org>
> wrote:
>
> >Greg Brewer wrote:
> >>
> >> I agree with you on you last point but how would you feel about a proposal
> >> that would make calling
> >>   void f(char *);
> >>   void f(int);
> >> with
> >>    f(NULL);
> >> and
> >>    f(0);
> >> no longer abiguous?
> >>
> >
> >They are not currently ambiguous. Both call f(int).
>
> Am I missing something?  What if NULL is defined as 0L?

You're missing my overgeneralization. Yes, NULL could be defined as 0L,
and with these overloads f(NULL) would be ambiguous. But I don't think
that was the point that he was trying to make...

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


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jeff Rife <jrifeSPAM@BEnabsGONE.net>
Date: 1999/08/19
Raw View
Pete Becker (petebecker@acm.org) wrote:

> Greg Brewer wrote:
> >
> > I agree with you on you last point but how would you feel about a proposal
> > that would make calling
> >   void f(char *);
> >   void f(int);
> > with
> >    f(NULL);
> > and
> >    f(0);
> > no longer abiguous?
> >
>
> They are not currently ambiguous. Both call f(int).

I think that Greg is using ambiguous in a different manner from the
standard writers (correct me if I am wrong, Greg).

I think he means "non-intuitive", because we have had it drilled into
us that NULL is a "null-pointer constant", so it is a pointer, so it
should call the function with the pointer argument.

We *know* that won't happen with the way overloading is defined in
the standard, for this set of functions and arguments, but that is the
whole point of this thread:

What good is a "null-pointer constant", if it isn't actually a const
pointer to nowhere?

The language of the standard should make any English-speaking person
expect a different behavior from f(NULL), thus, the "non-intuitive".

--
Jeff Rife                   | "Hey, dogs guard.
19445 Saint Johnsbury Lane  |  Cats watch...and judge."
Germantown, MD  20876-1610  |
Home: 301-916-8131          |              -- Salem the Cat
Work: 301-770-5800 Ext 5335 |


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/08/19
Raw View
In article <7pdh80$qaf$1@engnews1.eng.sun.com>,
  clamage@eng.sun.com (Steve Clamage) wrote:
> stanley@West.Sun.COM (Stanley Friesen [Contractor]) writes:

> >The special case would be exactly and only the token sequence "(void
> >*)0".  There is no reason to extend it to integers that happen to
> >have the value zero.  That is not particularly useful.

> But there is utility in accepting the same null pointer constants that
> C accepts.

> In C, any constant integer expression with value 0, or that value cast
> to void*, is a null pointer constant. I don't see the benefit in
> accepting (void*)0 but rejecting, for example, ((void*)0L).

Agreed.  *If* any such extension is considered, it should use the same
criteria as C: an integral constant expression evaluating to zero
<addition>, or such an expression cast to void*</addition>.  While I
would never really expect to see anything other than 0, 0L or
((void*)0), I can see no real value in restricting it to a specific
token sequence.

The more I think about it, the more I think that that (and requiring
NULL to be defined as "((void*)0)" is the only change needed.  While
void* does not normally implicitly convert to other pointer types in
C++, neither does 0.  And while the type of ((void*)0) is void*,
defining it as a null pointer constant would permet the conversion in
this special case.

Having said that, of course, I should point out that the *only* real win
is to ensure that NULL can only be used in a pointer context.  It
doesn't stop any of the existing misuses of 0 or implicit conversion to
bool.  It does mean that people like myself who prefer NULL can use it
without worrying that it will have unexpected repercusions on function
overloading (f(NULL) calling f(int)).

I now remember why a new type was considered preferable: it could be
declared illegal to pass an instance of this type to a vararg.
Requiring NULL to have this type would mean that errors like:

    execl( "Prog" , "Prog" , "anArg" , NULL ) ;

would be flagged by the compiler, rather than simply resulting in
undefined behavior.

(On second thought, I'm not sure whether this is a good idea.  Vararg
functions are fairly rare, and most of the ones I've seen are like the
above, and take either void* or char*.  Given that the standard more or
less requires the same representation of void* and char*, it is hard to
imagine an implementation where the undefined behavior in the above case
would do anything but work.  And I'm sure that there is a large body of
code which does just this, at least in C.)

Anyway, one of the reasons my proposal was so simple was the lack of
time.  This is no longer a reason, as we have at least a couple of years
before any new proposal can be considered.  I'd be interested in seeing
one which took the route of the separate type, if only to see what the
impact really is.

--
James Kanze                   mailto: James.Kanze@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.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Pete Becker <petebecker@acm.org>
Date: 1999/08/19
Raw View
Greg Brewer wrote:
>
> Pete Becker <petebecker@acm.org> wrote in message
> news:37BB6D8B.ADD24984@acm.org...
> > > I agree with you on you last point but how would you feel about a
> proposal
> > > that would make calling
> > >   void f(char *);
> > >   void f(int);
> > > with
> > >    f(NULL);
> > > and
> > >    f(0);
> > > no longer abiguous?
> > They are not currently ambiguous. Both call f(int).
>
> Not according to Borland C++ 5.01.  Which is preferable to in the case of
> f(NULL).
>

If you want to do compiler polls, Borland C++ 5.3 doesn't complain about
ambiguity. Neither does VC++ 5.0 nor VC++ 6.0, nor gcc (egcs-1.1.2), nor
the Edison Design Group compiler. gcc resolves f(NULL) to f(void*)
because of its definition of NULL as __null. All the others resolve
f(NULL) to f(int), and all five compilers resolve f(0) to f(int).

But more to the point is that the language definition says that these
calls are not ambiguous. 0 as a null pointer constant can be converted
to a null pointer in order to call f(char*), but as an int it needs no
conversion in order to call f(int), so f(int) is the correct choice.

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


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: source@netcom.com (David Harmon)
Date: 1999/08/19
Raw View
On 18 Aug 1999 05:31:47 GMT in comp.std.c++, stanley@West.Sun.COM
(Stanley Friesen [Contractor]) wrote:

>>Would that make the following code legal:
>>
>>const int i=0;
>>char *pc=(void*)i;
>
>If I had my way: no, never.
>
>The special case would be exactly and only the token sequence "(void *)0".
>There is no reason to extend it to integers that happen to have the value
>zero.

That would be an unfortunate inconsistancy to introduce when all
constant integer expressions with the value zero are null pointer
constants, not just the one spelled 0 .



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Greg Brewer" <nospam.gregb@hal-pc.org>
Date: 1999/08/18
Raw View
> Globally, I think that there is a sort of a concensus that the problem
> needs fixing, but absolutly no concensus as to how.  (And there are
> people who are convinced that any fix worth the effort would break too
> much code to be considered.  Even I would object to a change that would
> make "char* p = 0" illegal.)

I agree with you on you last point but how would you feel about a proposal
that would make calling
  void f(char *);
  void f(int);
with
   f(NULL);
and
   f(0);
no longer abiguous?




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: stanley@West.Sun.COM (Stanley Friesen [Contractor])
Date: 1999/08/18
Raw View
In article <37B7C714.44E4EFB4@lucent.com>, Salters  <salters@lucent.com> wrote:
>
>Francis Glassborow wrote:
>> Why?  Could we not revisit the decision in the next version of C++?  Can
>> anyone give a good reason why making (void *)0 a special case would be a
>> problem.  BTW I would require exactly that C style cast mechanism.
>
>Would that make the following code legal:
>
>const int i=0;
>char *pc=(void*)i;

If I had my way: no, never.

The special case would be exactly and only the token sequence "(void *)0".
There is no reason to extend it to integers that happen to have the value
zero.  That is not particularly useful.

The specified token sequence should be specified to be the null-pointer
constant, and be implicitly convertable into any object pointer type,
generating the null pointer of that type.

The conversion of the integral constant 0 (zero) to a null pointer should
also be maintained for compatibility, though it might well be deprecated.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/16
Raw View
In article <p6qn1vvob7z.fsf@informatik.hu-berlin.de>, Martin von Loewis
<loewis@informatik.hu-berlin.de> writes
>> As far as I can tell there is no good reason for this.
>> IMHO the change to disallow `(void *)0' as a null pointer
>> constant in C++ was just a bad decision.
>
>Even if it was a bad decision: so what? This thread started with the
>question: Why was this decision made?, not Was it a good decision?
>
>> For a long time, it caused problems with C header files that defined
>> NULL as `(void *)0'.
>
>Now that these problems are solved (on many systems), it is important
>that it stays that way - any further change will cause further
>problems.

Why?  Could we not revisit the decision in the next version of C++?  Can
anyone give a good reason why making (void *)0 a special case would be a
problem.  BTW I would require exactly that C style cast mechanism.


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
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1999/08/16
Raw View
bs@research.att.com (Bjarne Stroustrup) writes:

>From: fjh@cs.mu.OZ.AU (Fergus Henderson) writes
>
> > Given all these problems, I wonder why so many people try to
> > defend the current status quo, giving bogus explanations that the change
> > was needed "for type safety", "for compatibility with C", and so forth.
> > The explanations are bogus because the obvious solution of leaving
> > the definition of null pointer constant *exactly as it was in C*
> > also preserves type safety and compatibility with C -- indeed, it
> > preserves compatibility with C better than the current status quo did.
> >
> > I wish people would just admit that a bad decision was made.
>
>Please note that I did not make a decision to change C++ in a way that
>was incompatible with C; nor did the ISO C++ committee. There simply
>was no change.

Fair enough.  My understanding of the history was mistaken.
I apologize for misrepresenting how things happened.
In the above, I should have talked about "the solution of
changing the definition of null pointer constant to the same
as it was in ANSI C" rather than "the obvious solution of leaving
the definition of null pointer constant exactly as it was in C".

As Francis Glasborough said, perhaps this solution was not obvious
at the time.  It seems pretty obvious to me now, but clearly it wasn't
obvious to you then.

I still think the decision to make no change was a bad decision.
Note that there _was_ an explicit decision made to make no change:
IIRC, there was a proposal from James Kanze to the ANSI/ISO C++ committee
to make the change that we're discussing, but unfortunately the committee
voted against it.  This was fairly late in the process, though.

>The null pointer in K&R C was defined exactly as in is now
>in C++. At some point in its work, the ANSI C committee gave void* a very
>special semantics (primarily) to allow things like
>
> struct S *p = malloc(sizeof(struct C);
>
>rather than requiring a cast as in K&R C (and C++):
>
> struct S *p = (struct S *)malloc(sizeof(struct C);
>
>This relaxation of the type system wasn't necessary in C++ (given new) and
>opens a type hole, so I didn't follow suit.  By the time ANSI C was approved
>(with the void* type hole), C++ had been defined and used without that hole
>and compatible with C for about five years.

OK.  But in addition to allowing implicit conversions from `void *' to other
pointer types, the ANSI C committee also changed the definition of null
pointer constant.  The latter change did not weaken type safety at all.
It's a pity that you didn't follow suit on that change.

>At some point, it was discovered that given ANSIC C type rules, benefits
>could be had by using (void*)0 as the null pointer.

Here you talk about "ANSI C type rules", lumping them all together.
But the ANSI C rule which defines null pointer constants is separate
from the ANSI C rule which allows implicit conversions from `void *'
to other pointer types.  The people on the ANSI C committee who changed
the definition of null pointer constant to allow `(void *)0' must surely
have understood, before 1989, that this could have benefits (otherwise
why change it?).

>I think a good argument can be made for introducing a null pointer
>(with some suitable notation) into C++, but I don't see a good argument
>for simply adopting the void* hole in the type system from C.

I agree that adopting C's `void *' hole in C++ would be a bad idea.
But it's a pity that the C++ designers didn't recognize earlier
that allowing `(void *)0' as a null pointer constant was separate from
allowing implicit conversions from `void *' to other types.

--
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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1999/08/16
Raw View
bs@research.att.com (Bjarne Stroustrup) writes:

>From: David R Tribble <david@tribble.com> writes:
>
> > But '(void*)0' could have been deemed a special case in C++, so that
> > it would be treated like a true generic null pointer constant, and
> > not simply as a pointer-to-void.  This special case could have been
> > made without opening up the while void* type hole.
> >
> > Given this special handling of '(void*)0', all of the statements
> > above would still be illegal, but the following statements would now
> > be legal in both C and C++:
> >
> >     char * pc = (void*)0;
> >     void * pv = (void*)0;
> >     int *  pi = (void*)0;
> >
> > The benefit of this approach over other proposal (such as adding
> > a 'null' or '__null__' keyword, or inventing new syntax like '&0')
> > is that it doesn't affect any existing C++ or C code.  It's also a
> > pretty trivial change to make to the standard.
>
>However, nobody considered the issue important enough to do
>the work of presenting and analysing the alternatives and presenting a
>specific and detailes proposal.

I thought James Kanze did make a specific and detailed proposal along these
lines to the C++ committee.  (I don't know whether his proposal presented
or analyzed the alternatives.)

--
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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Salters <salters@lucent.com>
Date: 1999/08/16
Raw View
Francis Glassborow wrote:

> In article <p6qn1vvob7z.fsf@informatik.hu-berlin.de>, Martin von Loewis
> <loewis@informatik.hu-berlin.de> writes
> >> As far as I can tell there is no good reason for this.
> >> IMHO the change to disallow `(void *)0' as a null pointer
> >> constant in C++ was just a bad decision.

> >Even if it was a bad decision: so what? This thread started with the
> >question: Why was this decision made?, not Was it a good decision?
> >
> >> For a long time, it caused problems with C header files that defined
> >> NULL as `(void *)0'.

> >Now that these problems are solved (on many systems), it is important
> >that it stays that way - any further change will cause further
> >problems.

> Why?  Could we not revisit the decision in the next version of C++?  Can
> anyone give a good reason why making (void *)0 a special case would be a
> problem.  BTW I would require exactly that C style cast mechanism.

Would that make the following code legal:

const int i=0;
char *pc=(void*)i;

or even

int i=0;
char *pc=(void*)i; // could throw bad cast exception if i!=0

?

Michiel Salters


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/08/17
Raw View
Salters wrote:
>
> Francis Glassborow wrote:
>
> > In article <p6qn1vvob7z.fsf@informatik.hu-berlin.de>, Martin von Loewis
> > <loewis@informatik.hu-berlin.de> writes
> > >> As far as I can tell there is no good reason for this.
> > >> IMHO the change to disallow `(void *)0' as a null pointer
> > >> constant in C++ was just a bad decision.
>
> > >Even if it was a bad decision: so what? This thread started with the
> > >question: Why was this decision made?, not Was it a good decision?
> > >
> > >> For a long time, it caused problems with C header files that defined
> > >> NULL as `(void *)0'.
>
> > >Now that these problems are solved (on many systems), it is important
> > >that it stays that way - any further change will cause further
> > >problems.
>
> > Why?  Could we not revisit the decision in the next version of C++?  Can
> > anyone give a good reason why making (void *)0 a special case would be a
> > problem.  BTW I would require exactly that C style cast mechanism.
>
> Would that make the following code legal:
>
> const int i=0;
> char *pc=(void*)i;
>
> or even
>
> int i=0;
> char *pc=(void*)i; // could throw bad cast exception if i!=0
>
> ?

The most logical desition would probably be to make
(void*)expr a null pointer constant whenever expr itself is currently
a null pointer constant. From this rule, the first one would be
valid (i is a constant integral expression evaluating to 0,
therefore it is a null pointer constant today, and therefore
(void*)i should be a null pointer constant as well). The second
one would be a compile time error, of course.

The test with this rule would be quite easy:

"char* p = (void*)expr" is legal iff both
"char* p = expr" and "int ii = expr" are legal.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/17
Raw View
In article <37B7C714.44E4EFB4@lucent.com>, Salters <salters@lucent.com>
writes
>Would that make the following code legal:
>
>const int i=0;
>char *pc=(void*)i;

That would be up to us to decide, my vote would be for no.
>
>or even
>
>int i=0;
>char *pc=(void*)i; // could throw bad cast exception if i!=0

Definitely not.  In this context i is not a compile time constant.



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
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 1999/08/17
Raw View
Fergus Henderson wrote in message <7p8fqi$fc2
>But it's a pity that the C++ designers didn't recognize earlier
>that allowing `(void *)0' as a null pointer constant was separate from
>allowing implicit conversions from `void *' to other types.

Compilers are free to interpret "NULL" as an intention to use a
null pointer. They can issue warnings where the integer expansion
results in the selection of an "int" overload rather than a pointer
overload. I don't know of any other reason to "need" a null pointer
symbol, but presumably the same applies to those cases too.

So start bullying your compiler vendor.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/08/17
Raw View
In article <37B7C714.44E4EFB4@lucent.com>,
  Salters <salters@lucent.com> wrote:
>
> Francis Glassborow wrote:
>
> > In article <p6qn1vvob7z.fsf@informatik.hu-berlin.de>, Martin von
Loewis
> > <loewis@informatik.hu-berlin.de> writes
> > >> As far as I can tell there is no good reason for this.
> > >> IMHO the change to disallow `(void *)0' as a null pointer
> > >> constant in C++ was just a bad decision.

> > >Even if it was a bad decision: so what? This thread started with
> > >the question: Why was this decision made?, not Was it a good
> > >decision?

> > >> For a long time, it caused problems with C header files that
> > >> defined NULL as `(void *)0'.

> > >Now that these problems are solved (on many systems), it is
> > >important that it stays that way - any further change will cause
> > >further problems.

> > Why?  Could we not revisit the decision in the next version of C++?
> > Can anyone give a good reason why making (void *)0 a special case
> > would be a problem.  BTW I would require exactly that C style cast
> > mechanism.

> Would that make the following code legal:
>
> const int i=0;
> char *pc=(void*)i;
>
> or even
>
> int i=0;
> char *pc=(void*)i; // could throw bad cast exception if i!=0

No.  The actual proposal consisted of two parts:  1) The definition of a
null pointer constant was extended to say that 'an constant integral
expression evaluating to zero and cast to void*' was also a null pointer
constant, and 2) NULL was *required* to be defined as ((void*)0).  The
first is nothing more than the definition of a null pointer constant
from the C standard.

--
James Kanze                   mailto: James.Kanze@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.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/08/17
Raw View
In article <FGGtEt.8zG@research.att.com>,
  bs@research.att.com (Bjarne Stroustrup) wrote:
> From: David R Tribble <david@tribble.com> writes:

>  > But '(void*)0' could have been deemed a special case in C++, so
>  > that it would be treated like a true generic null pointer constant,
>  > and not simply as a pointer-to-void.  This special case could have
>  > been made without opening up the while void* type hole.

>  > Given this special handling of '(void*)0', all of the statements
>  > above would still be illegal, but the following statements would
>  > now be legal in both C and C++:

>  >     char * pc = (void*)0;
>  >     void * pv = (void*)0;
>  >     int *  pi = (void*)0;

>  > The benefit of this approach over other proposal (such as adding a
>  > 'null' or '__null__' keyword, or inventing new syntax like '&0') is
>  > that it doesn't affect any existing C++ or C code.  It's also a
>  > pretty trivial change to make to the standard.

> However, nobody considered the issue important enough to do the work
> of presenting and analysing the alternatives and presenting a specific
> and detailes proposal.

I did.  My proposal was almost exactly what David Tribble is suggesting:
make the magic which is used for 'a integral constant expression
evaluating to 0' apply to the same, cast to void*, and require that NULL
be defined as ((void*)0).  I was unable to attend the meeting in which
it was discussed; Dag Bruck did me the honour of defending it.  The
proposal did not make it out of the working group.

I forget the reasons given for not adopting it at the time -- if I
remember correctly, at least some people rejected it because it didn't
go far enough.  In the mean time, I've lost considerable interest in the
question, for the simple reason that I find myself using smart pointers
most of the time anyway.

> I suspect that the real problem in this case
> would have been to deal with the multitude of competing solutions of
> the problem. People favoring one solution to the null pointer problem
> have often been somewhat intolerant of people favoring alternatives.

This is my impression as well.  I intentionally proposed a minimal
solution because it was late in the standardization proceedings, and I
feared anything more, like introducing a real null pointer type, would
cause additional delays.  (Another reason was that Fergus had
implemented my proposal in g++, so there was "existing practice", at
least to the point of knowing that it could be implemented at reasonable
cost.)  As I say, one of the reasons my proposal didn't pass is that it
didn't go far enough.

Globally, I think that there is a sort of a concensus that the problem
needs fixing, but absolutly no concensus as to how.  (And there are
people who are convinced that any fix worth the effort would break too
much code to be considered.  Even I would object to a change that would
make "char* p = 0" illegal.)

--
James Kanze                   mailto: James.Kanze@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.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/08/17
Raw View
In article <7p8g2f$ff7$1@mulga.cs.mu.OZ.AU>,
  fjh@cs.mu.OZ.AU (Fergus Henderson) wrote:
>
> bs@research.att.com (Bjarne Stroustrup) writes:
>
> >From: David R Tribble <david@tribble.com> writes:
> >
> > > But '(void*)0' could have been deemed a special case in C++, so
that
> > > it would be treated like a true generic null pointer constant, and
> > > not simply as a pointer-to-void.  This special case could have
been
> > > made without opening up the while void* type hole.
> > >
> > > Given this special handling of '(void*)0', all of the statements
> > > above would still be illegal, but the following statements would
now
> > > be legal in both C and C++:
> > >
> > >     char * pc = (void*)0;
> > >     void * pv = (void*)0;
> > >     int *  pi = (void*)0;
> > >
> > > The benefit of this approach over other proposal (such as adding
> > > a 'null' or '__null__' keyword, or inventing new syntax like '&0')
> > > is that it doesn't affect any existing C++ or C code.  It's also a
> > > pretty trivial change to make to the standard.
> >
> >However, nobody considered the issue important enough to do
> >the work of presenting and analysing the alternatives and presenting
a
> >specific and detailes proposal.

> I thought James Kanze did make a specific and detailed proposal along
> these lines to the C++ committee.  (I don't know whether his proposal
> presented or analyzed the alternatives.)

I did.  The analysis of the alternatives was largely limited to the
observation that they all involved the introduction of a new type, and
thus entailed a significant risk of delaying the standard.

This is largely from memory.  I've had two disk crashes since then, so
any copy of my proposal that I have is somewhere on a backup tape.  The
paper was submitted (and distributed?) in electronic form, so maybe
someone has a copy somewhere.  (The date would have been shortly after
the Munich meeting.)

--
James Kanze                   mailto: James.Kanze@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.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/08/17
Raw View
In article <7p8fqi$fc2$1@mulga.cs.mu.OZ.AU>,
  fjh@cs.mu.OZ.AU (Fergus Henderson) wrote:
> bs@research.att.com (Bjarne Stroustrup) writes:
>
> >From: fjh@cs.mu.OZ.AU (Fergus Henderson) writes

> > > Given all these problems, I wonder why so many people try to
> > > defend the current status quo, giving bogus explanations that the
> > > change was needed "for type safety", "for compatibility with C",
> > > and so forth.  The explanations are bogus because the obvious
> > > solution of leaving the definition of null pointer constant
> > > *exactly as it was in C* also preserves type safety and
> > > compatibility with C -- indeed, it preserves compatibility with C
> > > better than the current status quo did.

> > > I wish people would just admit that a bad decision was made.

> >Please note that I did not make a decision to change C++ in a way
> >that was incompatible with C; nor did the ISO C++ committee. There
> >simply was no change.

> Fair enough.  My understanding of the history was mistaken.  I
> apologize for misrepresenting how things happened.  In the above, I
> should have talked about "the solution of changing the definition of
> null pointer constant to the same as it was in ANSI C" rather than
> "the obvious solution of leaving the definition of null pointer
> constant exactly as it was in C".

> As Francis Glasborough said, perhaps this solution was not obvious at
> the time.  It seems pretty obvious to me now, but clearly it wasn't
> obvious to you then.

> I still think the decision to make no change was a bad decision.  Note
> that there _was_ an explicit decision made to make no change: IIRC,
> there was a proposal from James Kanze to the ANSI/ISO C++ committee to
> make the change that we're discussing, but unfortunately the committee
> voted against it.  This was fairly late in the process, though.

I did make a formal proposal.  Late in the process is relative,
however.  I made the simplest proposal possible, because I thought it
was *very* late in the process.  On the other hand, some significant
additions, like STL, occured still later (or at least as late).

It's also worth pointing out that my proposal was a minimal solution,
and that it didn't really solve everything.  I can no longer remember
the arguments, but I do remember that there were definite cases which a
true null keyword could have solved, but my proposal didn't.

Also, with regards to "obvious", the problem had been discussed quite
some time in comp.lang.c++, by many of the most competent practitionners
before it occured to anyone that simply applying the meta-magic used
with 0 to (void*)0 would solve a significant part of the problem.  So
the solution was far from obvious.  (I might add that the idea wasn't
from me.  If I recall correctly, it was someone from Isreal who
originally posted the question as to why such an "obvious" solution
wasn't used.)

--
James Kanze                   mailto: James.Kanze@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.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/08/13
Raw View
bs@research.att.com (Bjarne Stroustrup) writes:
>  char c;
>  char* pc = &c;
>  void* pv = pc; // legal C, not legal C++
>  int* pi = pv;
>  int i = *pi;

You mean this, of course -

  void* pv = pc;
  int* pi = pv; // legal C, not legal C++


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: bs@research.att.com (Bjarne Stroustrup)
Date: 1999/08/13
Raw View
rom: Hyman Rosen <hymie@prolifics.com> writes

> bs@research.att.com (Bjarne Stroustrup) writes:
> >       char c;
> >       char* pc = &c;
> >       void* pv = pc;  // legal C, not legal C++
> >       int* pi = pv;
> >       int i = *pi;
>
> You mean this, of course -
>
>         void* pv = pc;
>        int* pi = pv;   // legal C, not legal C++

Yes. Of course (oops!). Thanks.

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




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1999/08/14
Raw View
fjh@cs.mu.OZ.AU (Fergus Henderson) writes:

> As far as I can tell there is no good reason for this.
> IMHO the change to disallow `(void *)0' as a null pointer
> constant in C++ was just a bad decision.

Even if it was a bad decision: so what? This thread started with the
question: Why was this decision made?, not Was it a good decision?

> For a long time, it caused problems with C header files that defined
> NULL as `(void *)0'.

Now that these problems are solved (on many systems), it is important
that it stays that way - any further change will cause further
problems.

> Even now that the header file problems have been fixed, disallowing
> `(void *)0' for NULL makes it harder for compilers to give good
> diagnostics for misuses of NULL.

But compilers have learned to cope with it (at least, g++ has). It may
require some magic. Since the standard is not going to change soon,
this magic is well-invested.

> Given all these problems, I wonder why so many people try to defend
> the current status quo

Because it is good that it is well specified; whether you like the
specification or not.

> I wish people would just admit that a bad decision was made.

If that makes you happy: I admit it :-)

Regards,
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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <david@tribble.com>
Date: 1999/08/14
Raw View
Fergus Henderson wrote:
>> IMHO the change to disallow `(void *)0' as a null pointer
>> constant in C++ was just a bad decision.

Pete Becker wrote:
> There was no such decision. It is a consequence of the more general
> decision (made back in the dawn of time) that pointers to void are not
> implicitly convertible to other pointer types.

Bjarne Stroustrup wrote:
> Please note that I did not make a decision to change C++ in a way that
> was incompatible with C; nor did the ISO C++ committee. There simply
> was no change. The null pointer in K&R C was defined exactly as in is
> now in C++. At some point in its work, the ANSI C committee gave
> void* a very special semantics (primarily) to allow things like
>
>     struct S *p = malloc(sizeof(struct C);
>
> rather than requiring a cast as in K&R C (and C++):
>
>     struct S *p = (struct S *)malloc(sizeof(struct C);
>
> This relaxation of the type system wasn't necessary in C++ (given
> new) and opens a type hole, so I didn't follow suit. By the time
> ANSI C was approved (with the void* type hole), C++ had been defined
> and used without that hole and compatible with C for about five
> years.
>
> At some point, it was discovered that given ANSI C type rules,
> benefits could be had by using (void*)0 as the null pointer.
>
> I think a good argument can be made for introducing a null pointer
> (with some suitable notation) into C++, but I don't see a good
> argument for simply adopting the void* hole in the type system from
> C.
>
> The following should be rejected by a compiler:
>
>      char c;
>      char* pc = &c;
>      void* pv = pc;  // legal C, not legal C++
>      int* pi = pv;
>      int i = *pi;

But '(void*)0' could have been deemed a special case in C++, so that
it would be treated like a true generic null pointer constant, and
not simply as a pointer-to-void.  This special case could have been
made without opening up the while void* type hole.

Given this special handling of '(void*)0', all of the statements
above would still be illegal, but the following statements would now
be legal in both C and C++:

    char * pc = (void*)0;
    void * pv = (void*)0;
    int *  pi = (void*)0;

The benefit of this approach over other proposal (such as adding
a 'null' or '__null__' keyword, or inventing new syntax like '&0')
is that it doesn't affect any existing C++ or C code.  It's also a
pretty trivial change to make to the standard.

-- David R. Tribble, david@tribble.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/16
Raw View
In article <37B48FBA.2DE77379@tribble.com>, David R Tribble
<david@tribble.com> writes
>But '(void*)0' could have been deemed a special case in C++, so that
>it would be treated like a true generic null pointer constant, and
>not simply as a pointer-to-void.  This special case could have been
>made without opening up the while void* type hole.

Yes, it seems obvious now.  A pity it wasn't then.  Making (void*)0 a
special case was no different from making 0 a special case in the
context of pointers.


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
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1999/08/13
Raw View
Barry Margolin <barmar@bbnplanet.com> writes:

 >Greg Brewer <nospam.gregb@hal-pc.org> wrote:
 >>The first of the problems is what I term the zero problem.  When I write an
 >>overloaded function or template that can accept either a pointer or an
 >>integer value, the operation works fine unless the value I am sending it is
 >>either NULL or 0.  With those two values, the compiler issues an error about
 >>an ambiguous call.  I do understand that the problem is that a null pointer
 >>is just a 0 and NULL is simply a #define value for 0.
 >....
 >>Anyone care to comment why the current state is preferable?
 >
 >For compatibility with C.  This issue is apparently not considered enough
 >of a problem to warrant doing it differently than C does.

But C++ *does* do things differently than C does: C allows `(void *)0'
as a null pointer constant, whereas C++ does not.

As far as I can tell there is no good reason for this.
IMHO the change to disallow `(void *)0' as a null pointer
constant in C++ was just a bad decision.  For a long time,
it caused problems with C header files that defined NULL
as `(void *)0'.  And these problems encouraged people to
use 0 rather than NULL, which makes maintenance harder.
Even now that the header file problems have been fixed,
disallowing `(void *)0' for NULL makes it harder for compilers
to give good diagnostics for misuses of NULL.

Given all these problems, I wonder why so many people try to
defend the current status quo, giving bogus explanations that the change
was needed "for type safety", "for compatibility with C", and so forth.
The explanations are bogus because the obvious solution of leaving
the definition of null pointer constant *exactly as it was in C*
also preserves type safety and compatibility with C -- indeed, it
preserves compatibility with C better than the current status quo did.

I wish people would just admit that a bad decision was made.

--
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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Pete Becker <petebecker@acm.org>
Date: 1999/08/13
Raw View
Fergus Henderson wrote:
>
> IMHO the change to disallow `(void *)0' as a null pointer
> constant in C++ was just a bad decision.

There was no such decision. It is a consequence of the more general
decision (made back in the dawn of time) that pointers to void are not
implicitly convertible to other pointer types.

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


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]