Topic: NULL pointer
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/27 Raw View
stephen.clamage@Eng.Sun.COM (Steve Clamage) writes:
|> In article D1n5yEpfhOXV092yn@nada.kth.se, d96-mst@nada.kth.se
|> (Mikael Steldal) writes:
|> >In article <rf5n2u3wfm7.fsf@vx.cit.alcatel.fr>,
|> >James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
|> >
|> >>Also, for those not familiar with the term, type punning means telling
|> >>the compiler to access the actual bits as if they were a T, regardless
|> >>of what it thinks they are.
|> >
|> >It that what reinterpret_cast does?
|>
|> Here's a quote from the draft standard:
|>
|> "The mapping performed by reinterpret_cast is implementation-defined.
|> [Note: it might, or might not, produce a representation different from
|> the original value. ]"
|>
|> In other words, the result of a reinterpret_cast might or might not
|> change the bits, and usage is not portable.
|>
|> In addition, reinterpret_cast is allowed only for specified kinds of
|> conversion. It is not a general type-punning mechanism. (C++ doesn't
|> have a general type-punning mechanism.)
I believe, however, that the intent of the standard is that a
reinterpret_cast on a pointer will result in a pointer to the same
actual memory location, in so far as possible. (If the cast is to void*
or char*, it should always be possible.)
In this case, the reinterpret_cast may be used FOR type punning. It
doesn't do the punning itself, but provides a mechanism by which the
programmer can do it. For example, to look at the underlying
representation of a double:
double d ;
unsigned char* p = reinterpret_cast< unsigned char* >( &d ) ;
Dereferencing p is an example of what I would call type punning;
obtaining the correct initialization of p is only possible with
reinterpret_cast (or an old-style cast which works like a
reinterpret_cast).
Such type punning is definitly bad programming practice in general.
There are exceptions, though; I'd use something like this to implement
the library routines frexp and ldexp, for example, and I've used it in
the past to hack together an initial guess for a sqrt routine. I also
use it for implementing a stack walk-back. And of course, for
curiosity's sake, to see what the underlying representation looked like.
Of course, all of these uses except the last are extremely
implementation dependant. (Even given 8 bit bytes, 16 bit shorts, 64
bit doubles, IEEE format and linear addressing, the floating point
routines still need an #if on the byte ordering. And that's a lot of
givens to begin with.)
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/27 Raw View
David R Tribble <david.tribble@central.beasys.com> writes:
|> >|> I meant that '(void *)0' be interpreted by the compiler as meaning
|> >|> 'null pointer (of no particular type)'. This is similar, but
|> >|> better, than the way it stands now with '0' being interpreted as
|> >|> 'integer zero' or 'null pointer of no type'.
|> >|>
|> >|> So just because we could then define a macro like:
|> >|> #define NULL ((void *)0)
|> >|> Doesn't mean that 'NULL' has type 'pointer to void'.
|> >
|> > If "((void*)0)" doesn't have type "void*", how do you get a null pointer
|> > with type "void*"?
|>
|> Simple. '(void*)0' means 'typeless null pointer'. Explicitly casting it
|> to any pointer type, including void pointer, would give it a type:
So "typeid( (void*)0 ) != typeid( (void*)(void*)0 )"?
I'm not sure I like that.
(BTW: what should typeid return for the null pointer if it is a special
type?)
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/23 Raw View
David R Tribble <david.tribble@central.beasys.com> writes:
|> > "David R. Tribble" <david.tribble@central.beasys.com> wrote:
|> >
|> > |> BTW, Stroustrup mentioned a possible solution, one that is probably
|> > |> better than any mentioned to date:
|> > |>
|> > |> A void* cannot be assigned to anything without a cast. Allowing
|> > |> implicit conversions of void* to other pointer types would open a
|> > |> serious hole in the type system. One might make a special case
|> > |> for (void*)0, but special cases should only be admitted in dire need.
|> > |> -- From D&E, p.230.
|> > |>
|> > |> I like this idea. How do I love it? Let me count the ways: ...
|>
|> >I agree Stroustrup's suggestion would be fairly simple to implement, but
|> >it would not be a sufficient solution. It's well understood that we want
|> >a NULL which is not an int before it's a pointer. By the same reasoning,
|> >we also need a NULL which is not a void pointer before it is any other
|> >pointer.
|>
|> I wasn't clear on this point in my original letter.
|>
|> I meant that '(void *)0' be interpreted by the compiler as meaning 'null
|> pointer (of no particular type)'. This is similar, but better, than the way
|> it stands now with '0' being interpreted as 'integer zero' or 'null pointer
|> of no type'.
|>
|> So just because we could then define a macro like:
|>
|> #define NULL ((void *)0)
|>
|> Doesn't mean that 'NULL' has type 'pointer to void'.
If "((void*)0)" doesn't have type "void*", how do you get a null pointer
with type "void*"? Maybe "((void*)(char*)0)"? Or
"static_cast< void* >( 0 )" is the "typeless" null pointer, and
"reinterpret_cast< void* >( 0 )" the void* null pointer? Or assigning 0
to an int, and casting that to a "void*"? (But in fact, that isn't
currently guaranteed to give us a null pointer.)
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Ben Liblit <ben@ls.com>
Date: 1997/01/23 Raw View
hpa@transmeta.com (H. Peter Anvin) writes:
>
> int foo(char *, int, ...); // First arg char *, second int, N unknown
> int bar(char *, int ...); // First arg char *, N int arguments
>
> Someone else might be able to come up with a better syntax for this
> one...
Say, I like that idea. Can't say I've ever needed it in practice, but
it's still an interesting notion.
How about the following syntax:
int bar( char *format, int values[ ... ] );
The syntax suggests that "values" is array-like, and that's no
coincidence. I imagine that you would access the N int arguments
using array syntax:
int x = values[ 0 ] + values[ 1 ] * values[ 2 ];
Of course, it is up to you to figure out how many values there are,
presumably by looking at other arguments. That's no different than
the standard variadic arguments we have today.
I like "[...]" because it is evocative of both variadics and of
arrays. More importantly, it is not currently legal syntax. That
means that it would not break or silently change the behavior of any
pre-existing legal program. That's an extremely significant
consideration.
In declaractions, of course, the parameter name could be omitted:
int bar( char *, int [ ... ] );
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/23 Raw View
In article <rf5vi8opydm.fsf@vx.cit.alcatel.fr> James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
>David R Tribble <david.tribble@central.beasys.com> writes:
>
>|> >It's well understood that we want
>|> >a NULL which is not an int before it's a pointer. By the same reasoning,
>|> >we also need a NULL which is not a void pointer before it is any other
>|> >pointer.
>|>
>|> I meant that '(void *)0' be interpreted by the compiler as meaning 'null
>|> pointer (of no particular type)'. This is similar, but better, than the way
>|> it stands now with '0' being interpreted as 'integer zero' or 'null pointer
>|> of no type'.
>|>
>|> So just because we could then define a macro like:
>|>
>|> #define NULL ((void *)0)
>|>
>|> Doesn't mean that 'NULL' has type 'pointer to void'.
>
>If "((void*)0)" doesn't have type "void*", how do you get a null pointer
>with type "void*"? Maybe "((void*)(char*)0)"? Or
>"static_cast< void* >( 0 )" is the "typeless" null pointer, and
>"reinterpret_cast< void* >( 0 )" the void* null pointer? Or assigning 0
>to an int, and casting that to a "void*"? (But in fact, that isn't
>currently guaranteed to give us a null pointer.)
This continues to emphasize that we ain't gunna solve this problem
in this way. No amount of grafting is going to give it to us.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Marcelo Cantos <marcelo@mds.rmit.edu.au>
Date: 1997/01/23 Raw View
James Kanze wrote:
>
> Ted Clancy <s341282@student.uq.edu.au> writes:
>
> |> James Kanze wrote:
> |> >
> |> > Pete Becker <pbecker@oec.com> writes:
> |> >
> |> > |> Mikael St=E5ldal wrote:
> |> >
> |> > [Proposal for standard NULL...]
> |> > |> Since this is completely implementable in C++ as it exists in the
> |> > |> current working paper, you can do it in your own code today. What
> |> > |> benefits arise from adding it to the language standard?
> |> >
> |> > To avoid conflicts between multiple libraries defining it "almost" the
> |> > same way. To be able to use the same version with all libraries, and
> |> > not "NULL" with library X, "null" witl library Y, and "nil" with
> |> > library Z.
> |>
> |> Agreed! Not to mention that the current NULL is a MACRO, and it would be
> |> nice IMHO to make it redundant, and replace it with a namespace-friendly
> |> std::null.
>
> I'm not sure that it should be in a namespace. I think, for example,
> that in the standard library, operator new and operator delete are not
> in namespace std; null should behave the same way.
Agreed. NULL, if defined in the standard, should be special, a literal,
like 23, "abc" and false. Namespaces would have no bearing on this.
Marcelo Cantos
--
__________________________________________________
Multimedia Database Systems Group, RMIT, Australia
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: wharris@mail.airmail.net (Billy Harris)
Date: 1997/01/24 Raw View
>David R Tribble <david.tribble@central.beasys.com> writes:
>|> I meant that '(void *)0' be interpreted by the compiler as meaning 'null
>|> pointer (of no particular type)'. This is similar, but better, than
the way
>|> it stands now with '0' being interpreted as 'integer zero' or 'null pointer
>|> of no type'.
>|>
>|> So just because we could then define a macro like:
>|>
>|> #define NULL ((void *)0)
>|>
>|> Doesn't mean that 'NULL' has type 'pointer to void'.
I suggest that instead of treating the string "((void *)0)" as a mystical
null pointer of no particular type, that compilers treat the string "nil"
as a mystical null pointer of no particular type. In other words, lets get
rid of the #define.
--
Billy Harris
wharris@mail.airmail.net
wharris@vega.uta.edu
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/01/24 Raw View
>|> I meant that '(void *)0' be interpreted by the compiler as meaning 'null
>|> pointer (of no particular type)'. This is similar, but better, than the
>|> way it stands now with '0' being interpreted as 'integer zero' or 'null
>|> pointer of no type'.
>|>
>|> So just because we could then define a macro like:
>|> #define NULL ((void *)0)
>|> Doesn't mean that 'NULL' has type 'pointer to void'.
>
> If "((void*)0)" doesn't have type "void*", how do you get a null pointer
> with type "void*"?
Simple. '(void*)0' means 'typeless null pointer'. Explicitly casting it
to any pointer type, including void pointer, would give it a type:
#define NULL ((void *)0)
func(NULL); // Matches any func(TYPE*)
func((char *)NULL); // Matches only func(char*)
func((void *)NULL); // Matches only func(void*)
As a practical matter of convenience, a NULL without a cast would probably
match void* in preference to the other types (such as the first example
above). This ambiguity only seems to occur for overloaded functions
taking different pointer type args.
It might be just as reasonable to deem it ambiguous in this case, in which
case the first example would be flagged as ambiguous. Ambiguous cases
would thus require an explicit cast to disambiguate.
-- David R. Tribble, david.tribble@central.beasys.com --
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/01/24 Raw View
Ben Liblit writes:
> hpa@transmeta.com (H. Peter Anvin) writes:
>>
>> int bar(char *, int ...); // First arg char *, N int arguments
> int bar( char *format, int values[ ... ] );
> The syntax suggests that "values" is array-like, and that's no
> coincidence. I imagine that you would access the N int arguments
> using array syntax:
> int x = values[ 0 ] + values[ 1 ] * values[ 2 ];
Then why wouldn't you construct an actual array in the caller and pass
it as a pointer to int (declared as int[])?
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Chelly Green <chelly@eden.com>
Date: 1997/01/24 Raw View
[I made a mistake in the example code, please disregard the
earlier reply]
Ben Liblit wrote:
>
> hpa@transmeta.com (H. Peter Anvin) writes:
> >
> > int foo(char *, int, ...); // First arg char *, second int, N unknown
> > int bar(char *, int ...); // First arg char *, N int arguments
> >
> > Someone else might be able to come up with a better syntax for this
> > one...
Why not just use what is already provided with the language?
int _foo( char*, int nargs, int args [] );
// would probably take more 'a#' arguments
int _foo( char* p, int nargs, int a1 = 0, int a2 = 0 )
{
int args [2] = { a1, a2 };
return _foo( p, nargs, args );
}
inline int foo( char* p ) { return _foo( p, 0 ); }
inline int foo( char* p, int a1 ) { return _foo( p, 1, a1 ); }
inline int foo( char* p, int a1, int a2 ) { return _foo( p, 2, a1, a2 ); }
// etc.
Or use some container class to hold the integers.
> Say, I like that idea. Can't say I've ever needed it in practice, but
> it's still an interesting notion.
Hey, let's add lots of interesting, though not generally useful, stuff
to the language!
> How about the following syntax:
>
> int bar( char *format, int values[ ... ] );
It's so funny how people seem so caught up in the syntax. The operator
[] [] [] ... thread comes to mind. Back up and honestly evaluate the use
of a feature like this, considering ways of achieving it with the
language as it currently is defined.
> The syntax suggests that "values" is array-like, and that's no
> coincidence. I imagine that you would access the N int arguments
> using array syntax:
>
> int x = values[ 0 ] + values[ 1 ] * values[ 2 ];
>
> Of course, it is up to you to figure out how many values there are,
> presumably by looking at other arguments. That's no different than
> the standard variadic arguments we have today.
...
Anything that is as unsafe as variable number of arguments doesn't have
much of a chance, especially when it's basically an extension to it.
> I like "[...]" because it is evocative of both variadics and of
> arrays. More importantly, it is not currently legal syntax. That
> means that it would not break or silently change the behavior of any
> pre-existing legal program. That's an extremely significant
> consideration.
...
Yes, as are probably hundreds of others (OK, maybe not that many, but
many more than these few). It's entertaining to see everyone's feature
they'd like to add to the language. Me? I want this:
#pragma follow_standard_exactly
--
Chelly Green | chelly@eden.com | C++ - http://www.eden.com/~chelly
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: stephen.clamage@Eng.Sun.COM (Steve Clamage)
Date: 1997/01/24 Raw View
In article D1n5yEpfhOXV092yn@nada.kth.se, d96-mst@nada.kth.se (Mikael St ldal) writes:
>In article <rf5n2u3wfm7.fsf@vx.cit.alcatel.fr>,
>James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
>
>>Also, for those not familiar with the term, type punning means telling
>>the compiler to access the actual bits as if they were a T, regardless
>>of what it thinks they are.
>
>It that what reinterpret_cast does?
Here's a quote from the draft standard:
"The mapping performed by reinterpret_cast is implementation defined.
[Note: it might, or might not, produce a representation different from
the original value. ]"
In other words, the result of a reinterpret_cast might or might not
change the bits, and usage is not portable.
In addition, reinterpret_cast is allowed only for specified kinds of
conversion. It is not a general type-punning mechanism. (C++ doesn't
have a general type-punning mechanism.)
---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/20 Raw View
Pete Becker <pbecker@oec.com> writes:
|> Mikael St=E5ldal wrote:
[Proposal for standard NULL...]
|> Since this is completely implementable in C++ as it exists in the
|> current working paper, you can do it in your own code today. What
|> benefits arise from adding it to the language standard?
To avoid conflicts between multiple libraries defining it "almost" the
same way. To be able to use the same version with all libraries, and
not "NULL" with library X, "null" witl library Y, and "nil" with library
Z.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/20 Raw View
comeau@panix.com (Greg Comeau) writes:
|> In article <rf5vi99vj5t.fsf@vx.cit.alcatel.fr> James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
|> >Note that according to the current draft, "When there is no parameter
|> >for a given argument, [...] if the argument has a non-POD class type,
|> >the behavior is undefined." Formally, this means that the library
|> >solution for NULL also results in undefined behavior.
|>
|> At least one version of the NULL class presented was a POD.
|> Have I misunderstood your point?
Which version. The library proposal I saw had member functions (in
fact, a user defined conversion operator). I think this is enough for
it not to be a POD.
|> > In practice, the
|> >compiler can easily determine this, and generate an error.
|>
|> Determine what? That you passed a NULL object (in the lib version)?
That you have passed a non-POD class type to a vararg.
|> > (Can anyone
|> >explain to me *WHY* this is undefined behavior, and not an error
|> >requiring a diagnostic?) (Note that the current situation results in an
|> >error that is impossible for the compiler to detect, and will work in
|> >most cases, so the error generally goes undetected. Even if the
|> >compiler doesn't detect the error with the library solution, it is
|> >highly unlikely that the resulting program will work. Also, I think
|> >that if the library solution adds a private copy constructor, it should
|> >give a diagnosible error in this case.)
|>
|> It's certainly in the spirit of other similar rules.
Like, for example, using two successive underscores in a symbol name:
a__b. I can't really believe that this should be undefined.
|> Anyway, I never thought about this. I guess for cross language calls?
|> Baggage/mechanisms to support it can be provided but are not mandated?
I suspect that the reason is to allow implementations to make it work.
Frankly, given the fact that it is not guaranteed, I'd just as soon make
it illegal.
IMHO, good compilers will generate an error in both of the above cases
(double underscore, and non-POD to a vararg).
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/01/20 Raw View
James Kanze writes, concerning NULL:
>However...
>|> 8) It solves the variadic function problem:
>|> int varfunc(int a, ...);
>|> ...
>|> i = varfunc(3, "abc", NULL); // NULL is void*, not a class
>
>Not quite. If "varfunc" reads the pointer using "va_arg( char* )", then
>you have undefined behavior. If "varfunc" reads the pointer using
>"va_arg( int* )", then there are real machines on which it will fail.
The rule to follow with variadic functions is to pass the right type for each
argument as needed. If the function expects 'char *', then pass it a 'char *'
(such as '(char *)NULL'), and not something else.
On the other hand, according to ANSI C (which I assume C++ builds upon), a
'void *' pointer can hold a pointer of any other type. Casting a 'void *' to
'int *', for example, results in a valid integer pointer value. Similarly,
passing 'NULL' as a 'void *' to a function should allow the function to
treat it like any pointer type.
-- David R. Tribble, david.tribble@central.beasys.com --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/21 Raw View
David R Tribble <david.tribble@central.beasys.com> writes:
|> James Kanze writes, concerning NULL:
|> >However...
|> >|> 8) It solves the variadic function problem:
|> >|> int varfunc(int a, ...);
|> >|> ...
|> >|> i = varfunc(3, "abc", NULL); // NULL is void*, not a class
|> >
|> >Not quite. If "varfunc" reads the pointer using "va_arg( char* )", then
|> >you have undefined behavior. If "varfunc" reads the pointer using
|> >"va_arg( int* )", then there are real machines on which it will fail.
|>
|> The rule to follow with variadic functions is to pass the right type for each
|> argument as needed. If the function expects 'char *', then pass it a 'char *'
|> (such as '(char *)NULL'), and not something else.
|>
|> On the other hand, according to ANSI C (which I assume C++ builds upon), a
|> 'void *' pointer can hold a pointer of any other type. Casting a 'void *' to
|> 'int *', for example, results in a valid integer pointer value. Similarly,
|> passing 'NULL' as a 'void *' to a function should allow the function to
|> treat it like any pointer type.
Correct, but irrelevant. The exact rule is that any pointer type can be
CONVERTED to void* and back to the original type without loss of
information. In the context of the C standard, "converted" means more
or less a static_cast, and in any case, a cast or an implicit type
conversion. It does not mean, for example, that I can do type punning
on the pointer itself, and expect it to work, or that I can write a
void* into a union, and read it as a T*, and expect it to work.
In the case of stdarg.h, the C standard is quite explicit in saying that
the type extracted must exactly match the type actually passed (after
promotion, etc.). There are no conversions involved, and the guarantee
concerning void* doesn't apply. The reason for this is precisely that
most, if not all, implementations, use type punning somewhere in the
va_arg macro to extract the argument; if you pun to the original type
(about which all information has been lost), it will work, but nothing
else is guaranteed.
FWIW: a strict reading of the C standard would seem to imply that even a
mismatch on cv-qualifiers will result in undefined behavior. Thus, if
the function extracts a "char const*", and you pass it a string literal,
you have undefined behavior. In fact, I doubt that this was intended,
and I feel very sure that there will never be a real implementation
where it will fail.
Of course, on many implementations, all pointers have the same
representation, and the null pointer has the same representation what is
defined by the macro NULL (either 0, 0L or, in C, ((void*)0)). So
broken code will appear to work. This is not guaranteed, however.
IMHO: a quality implementation will pass additional hidden type
information when passing an argument which matches a ..., and the va_arg
macro will expand to invoke a compiler built-in which extracts and
verifies this information. (I don't know of any implementation which
actually does this, however.)
Also, for those not familiar with the term, type punning means telling
the compiler to access the actual bits as if they were a T, regardless
of what it thinks they are. Thus, for example:
void* p ;
f( (char*)p ) ; // Conversion.
f( *((char**)( &p ) ) ) ; // Type pun
Note that the conversion may change the representation (except maybe in
the case where only the cv-qualifiers are changed).
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Ted Clancy <s341282@student.uq.edu.au>
Date: 1997/01/21 Raw View
James Kanze wrote:
>
> Pete Becker <pbecker@oec.com> writes:
>
> |> Mikael St=E5ldal wrote:
>
> [Proposal for standard NULL...]
> |> Since this is completely implementable in C++ as it exists in the
> |> current working paper, you can do it in your own code today. What
> |> benefits arise from adding it to the language standard?
>
> To avoid conflicts between multiple libraries defining it "almost" the
> same way. To be able to use the same version with all libraries, and
> not "NULL" with library X, "null" witl library Y, and "nil" with library
> Z.
>
> --
> James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
> office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
> GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
> -- Conseils en informatique industrielle --
Agreed! Not to mention that the current NULL is a MACRO, and it would be
nice IMHO to make it redundant, and replace it with a namespace-friendly
std::null.
Also, the current definition of a POD NULL allows NULL to be passed to a
varargs uncast. This is type-unsafe and non-portable (Some platforms
define NULL as an int, some as a long, some as a void*. Also see other
posts for more info). NULL should not be a POD type.
Adding a non-POD null to the standard library would encourage compiler
vendors to display warnings/errors when a non-POD object is passed to a
varargs, to prevent null being passed to a varargs.
--
Ted Clancy
s341282@student.uq.edu.au
B Engineering, University of Queensland.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Ted Clancy <s341282@student.uq.edu.au>
Date: 1997/01/21 Raw View
James Kanze wrote:
>
> "David R. Tribble" <david.tribble@central.beasys.com> writes:
>
> [Concerning NULL...]
> |> BTW, Stroustrup mentioned a possible solution, one that is probably
> |> better than any mentioned to date:
> |>
> |> A void* cannot be assigned to anything without a cast. Allowing
> |> implicit conversions of void* to other pointer types would open a
> |> serious hole in the type system. One might make a special case
> |> for (void*)0, but special cases should only be admitted in dire need.
> |> -- From D&E, p.230.
> |>
> |> I like this idea. How do I love it? Let me count the ways:
>
> I like it too. (Obviously, since it was precisely what I proposed.)
> However...
>
[snip]
>
> --
> James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
> office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
> GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
> -- Conseils en informatique industrielle --
I agree Stroustrup's suggestion would be fairly simple to implement, but
it would not be a sufficient solution. It's well understood that we want
a NULL which is not an int before it's a pointer. By the same reasoning,
we also need a NULL which is not a void pointer before it is any other
pointer.
For example:
#define NULL (void*)0 //and allow implicit conversion to int*
void f(int *);
f(NULL); //successfully calls f(int *)
Now add:
void f(void *); //The meaning of the previous line SILENTLY changes
I think one of the library non-int, non-void pointer ideas would be
better.
--
Ted Clancy
s341282@student.uq.edu.au
B Engineering, University of Queensland.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/01/22 Raw View
> "David R. Tribble" <david.tribble@central.beasys.com> wrote:
>
> |> BTW, Stroustrup mentioned a possible solution, one that is probably
> |> better than any mentioned to date:
> |>
> |> A void* cannot be assigned to anything without a cast. Allowing
> |> implicit conversions of void* to other pointer types would open a
> |> serious hole in the type system. One might make a special case
> |> for (void*)0, but special cases should only be admitted in dire need.
> |> -- From D&E, p.230.
> |>
> |> I like this idea. How do I love it? Let me count the ways: ...
>I agree Stroustrup's suggestion would be fairly simple to implement, but
>it would not be a sufficient solution. It's well understood that we want
>a NULL which is not an int before it's a pointer. By the same reasoning,
>we also need a NULL which is not a void pointer before it is any other
>pointer.
I wasn't clear on this point in my original letter.
I meant that '(void *)0' be interpreted by the compiler as meaning 'null
pointer (of no particular type)'. This is similar, but better, than the way
it stands now with '0' being interpreted as 'integer zero' or 'null pointer
of no type'.
So just because we could then define a macro like:
#define NULL ((void *)0)
Doesn't mean that 'NULL' has type 'pointer to void'. On the contrary, it has
type 'null pointer'. It can thus be used anywhere a pointer (of any type)
fits.
This makes this example ambiguous:
void foo(char *p);
void foo(int *p);
foo(NULL); // Ambiguous, NULL has no specific type
The correct form for this situation would be to disambiguate the call by using
an explicit cast:
foo((char *)NULL);
(The cast is also required when passing NULL to a variadic function, since
the function expects a pointer to a particular type.)
On the other hand, if a function taking a bona fide void pointer is in scope,
the call could be deemed unambiguous, choosing the overloaded void* func in
preference to the others:
void foo(int *p);
void foo(void *p);
foo(NULL); // Defaults to calling foo(void*)
Or, we could deem the situtation ambiguous and require an explicit cast (even
a cast like (void*)NULL).
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/22 Raw View
Ted Clancy <s341282@student.uq.edu.au> writes:
|> James Kanze wrote:
|> >
|> > Pete Becker <pbecker@oec.com> writes:
|> >
|> > |> Mikael St=E5ldal wrote:
|> >
|> > [Proposal for standard NULL...]
|> > |> Since this is completely implementable in C++ as it exists in the
|> > |> current working paper, you can do it in your own code today. What
|> > |> benefits arise from adding it to the language standard?
|> >
|> > To avoid conflicts between multiple libraries defining it "almost" the
|> > same way. To be able to use the same version with all libraries, and
|> > not "NULL" with library X, "null" witl library Y, and "nil" with library
|> > Z.
|>
|> Agreed! Not to mention that the current NULL is a MACRO, and it would be
|> nice IMHO to make it redundant, and replace it with a namespace-friendly
|> std::null.
I'm not sure that it should be in a namespace. I think, for example,
that in the standard library, operator new and operator delete are not
in namespace std; null should behave the same way.
|> Also, the current definition of a POD NULL allows NULL to be passed to a
|> varargs uncast. This is type-unsafe and non-portable (Some platforms
|> define NULL as an int, some as a long, some as a void*. Also see other
|> posts for more info). NULL should not be a POD type.
|>
|> Adding a non-POD null to the standard library would encourage compiler
|> vendors to display warnings/errors when a non-POD object is passed to a
|> varargs, to prevent null being passed to a varargs.
Agreed, 100%.
I think that we have a good solution. I regret that this idea didn't
come up earlier. It is, however, far too late to consider an addition
to the current standard.
I can think of a couple of other "extensions" (garbage collection, hash
tables) which were proposed too late for the current standard. (In both
cases, the relative complexity, compared to null, was such that "too
late" was a lot earlier.) I would like to propose that we establish
some sort of "almost-standard" somewhere, so that implementors who wish
to add such extensions will do so in a compatible manner. This also has
the advantage that in the next round, we will have existing practice.
There are already formal proposals concerning garbage collection and
hash tables. We should probably do the same for this. (Writing a
formal proposal does not mean presenting it to the committee and
demanding a vote.) It would also be nice if there were a central site
which collected copies of such proposals.
I'd also stress the fact that the presence of a proposal at such a site
would not mean "this must be adopted by C++ in the next revision of the
standard", but only "if we want this, here is how it should be done".
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: hpa@transmeta.com (H. Peter Anvin)
Date: 1997/01/22 Raw View
Followup to: <rf5n2u3wfm7.fsf@vx.cit.alcatel.fr>
By author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
In newsgroup: comp.std.c++
>
> IMHO: a quality implementation will pass additional hidden type
> information when passing an argument which matches a ..., and the va_arg
> macro will expand to invoke a compiler built-in which extracts and
> verifies this information. (I don't know of any implementation which
> actually does this, however.)
>
Something that would be very nice to have in the standard
(unfortunately I think C++ not requiring a comma before the ellipsis
to be a grammar problem here) would be to support varadic functions
with a fixed type; often it seems to me varadic functions really only
are using a single type of data, or at least only pointers (which
could be converted to and from void *). It would be nice if:
int foo(char *, int, ...); // First arg char *, second int, N unknown
int bar(char *, int ...); // First arg char *, N int arguments
Someone else might be able to come up with a better syntax for this
one...
-hpa
--
This space intentionally has nothing but text explaining why this
space has nothing but text explaining that this space would otherwise
have been left blank, and would otherwise have been left blank.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1997/01/23 Raw View
In article <rf5n2u3wfm7.fsf@vx.cit.alcatel.fr>,
James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
>Also, for those not familiar with the term, type punning means telling
>the compiler to access the actual bits as if they were a T, regardless
>of what it thinks they are.
It that what reinterpret_cast does?
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/20 Raw View
"David R. Tribble" <david.tribble@central.beasys.com> writes:
[Concerning NULL...]
|> BTW, Stroustrup mentioned a possible solution, one that is probably
|> better than any mentioned to date:
|>
|> A void* cannot be assigned to anything without a cast. Allowing
|> implicit conversions of void* to other pointer types would open a
|> serious hole in the type system. One might make a special case
|> for (void*)0, but special cases should only be admitted in dire need.
|> -- From D&E, p.230.
|>
|> I like this idea. How do I love it? Let me count the ways:
I like it too. (Obviously, since it was precisely what I proposed.)
However...
|> 8) It solves the variadic function problem:
|> int varfunc(int a, ...);
|> ...
|> i = varfunc(3, "abc", NULL); // NULL is void*, not a class
Not quite. If "varfunc" reads the pointer using "va_arg( char* )", then
you have undefined behavior. If "varfunc" reads the pointer using
"va_arg( int* )", then there are real machines on which it will fail.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/20 Raw View
"David R. Tribble" <david.tribble@central.beasys.com> writes:
|> (BTW, this brings up a few questions about POSIX data types.
|> Specifically, how big are uid_t, gid_t, pid_t, off_t, et al? If I have
|> to print them, do I use "%d" or "%ld"? This is not a problem on 32-bit
|> systems, but it can be on 64-bit CPUs. Personally, I always cast them to
|> long and use "%ld".)
Which is the correct solution if they are guaranteed to be signed
integral types. (I don't have access to the POSIX standard, but the
same problem occurs in standard C/C++ with size_t and ptrdiff_t.)
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/01/15 Raw View
Ted Clancy writes:
> It's true that the absense of an op void* would prevent:
> comparing null to 0
Maybe an operator==(void*) could be provided. Or even a template
operator== for any pointer type.
> And I'll concede that giving the class a name might be necessary for the
> sake of sensible diagnostics, to provide a default constructor (since
> this null is an uninitialised const), and to _prevent_ passing to a ...
> (instead of just producing undefined behaviour) by a private copy ctor.
> I'm worried that people would try to overload functions on null, as has
> been suggested, but it wouldn't be smart for them to do so since a
> void f(Nulltype);
> wouldn't catch f(0), nor f(x) where x=0.
There's no way to prevent someone from overloading on class std::null
const&, if the class is given an name, is there?
> okay so we're looking at:
> namespace std {
> const class null {
> void operator&();
> null(const null&);
> public:
> null() {}
//Shouldn't the null() constructor be private too? Why would anyone
//construct another instance of class null?
//But then null could only be declared as a member of class null:
static const null null_constant;
> template <class T> operator T* () const { return 0; }
> template <class T, class C> operator T C::*() const { return 0;
> }
//> } null;
} null::null_constant, &null = null::null_constant;
> } //end namespace.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
Universidade Estadual de Campinas, SP, Brasil
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/01/15 Raw View
Ted Clancy <s341282@student.uq.edu.au> writes:
>... I'll concede that giving the class a name might be necessary for the
>sake of sensible diagnostics, to provide a default constructor (since
>this null is an uninitialised const), and to _prevent_ passing to a ...
>(instead of just producing undefined behaviour) by a private copy ctor.
I don't think giving it a private copy constructor will change the
status with regard to passing to a `...'. There's nothing in the DWP
that say that passing a class object to an elipsis calls the copy
constructor or requires the copy constructor to be accessible. It will
still be undefined behaviour. (Making it private might be useful in
practice, though, since it may be that more compilers issue a
diagnostic if the copy constructor is private than if it isn't.)
>[someone wrote:]
>> Mind you, I'm working from the premise that this is merely an exercise
>> (clearly it's not getting into the standard) and so what we have now
>> does not go away.
>
>I don't expect them to change the language specification for it, but I
>think it would would make a good addition to the standard library.
Unfortunately the time for additions to the standard library has passed.
>To whom do I write to suggest that? Hewlett-Packard? :-)
You should write to the C++ committee, but not now --
in about six years time, when they might start considering
the next version of the C++ standard.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/15 Raw View
Darron.Shaffer@beasys.com (Darron Shaffer) writes:
|> >The problem today is that NULL isn't an error. To take a classical
|> >example from the Unix kernal interface:
|> >
|> > execl( "/bin/someProgram" , "someProgram" , NULL ) ;
|> >
|> >This is supposed to replace the current process with the program in file
|> >"/bin/someProgram", with argv[ 0 ] == "someProgram", and argc == 1. In
|> >fact, it is undefined behavior! It will, however, work on a great many
|> >implementations, so the error is likely to go unnoticed for quite some
|> >time. (Actually, given that code like this exists in so many Unix
|> >applications, I suspect that any real implementation will do whatever is
|> >necessary to make it work. Proving the customer wrong has never been a
|> >particularly effective sales technique.)
|> >
|>
|> By the way, this will NOT work on one at least one current architecture:
|> OSF/1 on the Alpha.
|>
|> C: (with NULL defined as "((void *) 0)")
|>
|> execl("text", "text", NULL); // 3 64-Bit args: char *, char *, void *
|>
|> C++: (with NULL defined as "0")
|>
|> execl("text", "text", NULL); // 2 64-Bit args: const char *, const char *
|> // 1 32-Bit arg: int
|>
|> Oops, existing code just broke!
This is precisely my point about "real implementations doing whatever is
necessary to make it work." On this platform, any market-concious
implementor will define NULL as either "((void*)0)" or "0L", so that it
will seem to work (and so that he won't have to double the size of his
support staff). I'm sure that the popularity of "((void*)0)" on PC's is
due to the fact that this definition "works" in all of the compilation
models.
Note, however, that my point was somewhat stronger. There is NO legal
definition for NULL for which my example is defined by the language.
execl reads the NULL as a "char*" (or "const char*"); reading a va_arg
as a type other than what was actually passed is undefiend behavior,
according to the standard. (Actually, I'm not 100% sure about cv
qualifiers. If cv-qualifiers count, then if you can pass a string
literal (type char*), you cannot pass a char const*, and vice versa.)
Also, and I insist. Existing code didn't "just" break. It has always
been broken, from the day 1. It just seemed to work.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1997/01/13 Raw View
In article <32D50596.2AD4@oec.com>, Pete Becker <pbecker@oec.com> wrote:
>Since this is completely implementable in C++ as it exists in the
>current working paper, you can do it in your own code today. What
>benefits arise from adding it to the language standard?
It's nice to have such basic things in the standard so that you doesn't
have to include your own personal headers all the time.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Ted Clancy <s341282@student.uq.edu.au>
Date: 1997/01/14 Raw View
> >> The pro sides of course may be fine for some. The above has no thought
> >> whatsoever into deep dark pathological cases that no doubt exist.
> >> Anybody have any? OTOH, there is probably some instrumentation goodies
> >> one can get out of this if more is added. Just to recap, it seems we are
> >> looking at something more like this:
> >>
> >> const class Null {
> >> void operator&();
> >> Null(const Null&);
> >> public:
> >> template <class T> operator T* () const { return 0; }
> >> template <class T, class C> operator T C::*() const { return 0; }
> >> operator void*() const { return 0; }
> >>
> >> friend ostream& operator<<(ostream& o, const Null& me)
> >> { o << (void*)me; return o; } // if at all, assume void *?
> >> void *value() const { return 0; } // of any use???
> >> } Null;
> >>
> - Greg
> --
> Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
> Producers of Comeau C++ 4.0 front-end pre-release
> ****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
> Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
>
I've been thinking.
The problem with providing an op void* is that it makes null a void
pointer before it is any other pointer. That is almost as bad as making
0 an int before it is a pointer. For example:
The meaning of an existing
void f(char*);
f(null);
will be silently changed if a
void f(void*);
is added. Now f(null) calls f(void*) unambiguously
It's true that the absense of an op void* would prevent:
comparing null to 0
passing null to a ...
outputting null to an iostream
and other things of that nature, but these are all things which
shouldn't happen in C++. The first one makes no sense type wise
(pointer==int?), and the last two shouldn't be allowed as I've explained
before.
Existing code which do these things can continue to use #define NULL 0
or #define NULL 0L, or whatever. Newer code can use a typesafe
std::null. In your own words, "Either you're writing new code or using
old code. New code should use the new style."
And I'll concede that giving the class a name might be necessary for the
sake of sensible diagnostics, to provide a default constructor (since
this null is an uninitialised const), and to _prevent_ passing to a ...
(instead of just producing undefined behaviour) by a private copy ctor.
I'm worried that people would try to overload functions on null, as has
been suggested, but it wouldn't be smart for them to do so since a
void f(Nulltype);
wouldn't catch f(0), nor f(x) where x=0.
> Mind you, I'm working from the premise that this is merely an exercise
> (clearly it's not getting into the standard) and so what we have now
> does not go away.
I don't expect them to change the language specification for it, but I
think it would would make a good addition to the standard library. To
whom do I write to suggest that? Hewlett-Packard? :-)
okay so we're looking at:
namespace std {
const class null {
void operator&();
null(const null&);
public:
null() {}
template <class T> operator T* () const { return 0; }
template <class T, class C> operator T C::*() const { return 0;
}
} null;
} //end namespace.
Any suggestions?
--
Ted Clancy
s341282@student.uq.edu.au
B Engineering, University of Queensland.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1997/01/08 Raw View
In article <5arvl0$hc@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>I hope you at least agree that NULL has lived a life of debate and
>discussion.
Yes. I don't think that NULL is perfect in C, but it could be worse.
>>No, in most C compilers it would generate a diagnostic, but not in any
>>C++ compiler I've tried (test it with GCC and G++).
>
>What would? The two examples?
No, I'm only talking about the first example.
>The other was different function names, so I don't see it would be
>possible to diagnose this in C nor what the message would say????
On yhis program:
#include <stddef.h>
void f1(char*, long);
void f2(int, long);
int main(void)
{
long l = 5;
f1(0, l); /* oops, should have been f2() */
f2(NULL, l*2); /* oops, should have been f1() */
return 0;
}
gcc says:
test.c: In function `main':
test.c:11: warning: passing arg 1 of `f2' makes integer from pointer without a cast
g++ doesn't say anything on the same program.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/08 Raw View
Ted Clancy <s341282@student.uq.edu.au> writes:
|> It has been suggested that classes should not be allowed to be passed to
|> varadic argument functions (with exceptions for simple structs), which I
|> agree with. If that becomes part of the standard, having "null" being a
|> class object prevents it being passed to such a function without being
|> cast.
It is part of the standard. The only problem is, the result of trying
to do so is undefined behavior, and not a diagnosable error.
Declaring a private copy constructor should do the trick for null, but I
still think it would be worth changing the error from "undefined
behavior" to a "constraint violation" (which requires a compiler
diagnostic).
--
James Kanze home: kanze@gabi-soft.fr +33 (0)3 88 14 49 00
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
-- Conseils en informatique industrielle --
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Frank van Leeuwen" <fvl@iaehv.nl>
Date: 1997/01/08 Raw View
James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote in article
<rf5ybe5vkpl.fsf@vx.cit.alcatel.fr>...
> "David R. Tribble" <david.tribble@central.beasys.com> writes:
>
> |> Why not just add a 'null' keyword to the language and be done with
it?
>
> Because it isn't that simple. What is the type of `null'?
What about this???
function(c::null);
to pass a 'null' of type 'pointer to c'?
--------------------------------------------------------------------
Frank van Leeuwen fvl@iaehv.nl
"Any advertisments mailed to me can and will be used against you..."
--------------------------------------------------------------------
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Jason Merrill <jason@cygnus.com>
Date: 1997/01/08 Raw View
>>>>> James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
> "David R. Tribble" <david.tribble@central.beasys.com> writes:
> |> Why not just add a 'null' keyword to the language and be done with it?
> Because it isn't that simple. What is the type of `null'? If it is
> void*, we really haven't gained much with regards to "((void*)0)".
But the compiler doesn't have to treat it the same as ((void*)0). It can
be handled specially.
Jason
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1997/01/08 Raw View
In article <199701070407.UAA01752@taumet.eng.sun.com>,
stephen.clamage@Eng.Sun.COM (Steve Clamage) wrote:
>We could add a 'null' keyword to the language, but it wouldn't help much.
>The existing usage of anything that evaluates to a constant integer 0
>would still have to be allowed as a null pointer constant.
Yes, but I think that it's good enough anyway.
>The interactions of a 'null' keyword with the rest of the type system,
>with templates, and as actual arguments to a variadic function are
>not trivial to work out.
Maybe we could just use a null-class as proposed here, then very little
needs to be changed in the standard.
>To make 'null' useful, we'd have to accept breaking most existing code
>and make 'null' the only valid form of null pointer. (Possibly the
>macro NULL could be redefined to be 'null',
I think we should do like this:
* Introduce a new keyword or a mandatory object of a null-class and
call that "null", "nil" or something else than "NULL".
* Say that NULL have to be defined as "null", "nil" or what it will be
called.
* Continue to support using a litteral zero as a null pointer, maybe
require a warning and maybe consider it deprecated.
>but that would still break all code that depended on the old
>definition.
* Make sure that the new definition of NULL never will cause silent
changes, only errors when used wrong (assigning to integer, passing
uncast to vararg etc.). Maybe we have to accept ONE possible silent
change, the case of overloading pointers and integers (this does of
couse not apply to C code).
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/01/09 Raw View
Darron.Shaffer@beasys.com (Darron Shaffer) writes:
>[James Kanze writes:]
>> execl( "/bin/someProgram" , "someProgram" , NULL ) ;
>>
>>This is supposed to replace the current process with the program in file
>>"/bin/someProgram", with argv[ 0 ] == "someProgram", and argc == 1. In
>>fact, it is undefined behavior! It will, however, work on a great many
>>implementations, so the error is likely to go unnoticed for quite some
>>time. (Actually, given that code like this exists in so many Unix
>>applications, I suspect that any real implementation will do whatever is
>>necessary to make it work. Proving the customer wrong has never been a
>>particularly effective sales technique.)
>
>By the way, this will NOT work on one at least one current architecture:
>OSF/1 on the Alpha.
[...]
>(I haven't tried this, not having current access to an Alpha)
I have, and in fact it does work.
(On that platform, NULL is defined as 0L, and also I think everything
is converted to 64 bits for vararg functions anyway.)
I suspect James Kanze is right about the importance of commercial pressures.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Pete Becker <pbecker@oec.com>
Date: 1997/01/09 Raw View
Mikael St=E5ldal wrote:
>
> In article <199701070407.UAA01752@taumet.eng.sun.com>,
> stephen.clamage@Eng.Sun.COM (Steve Clamage) wrote:
> >We could add a 'null' keyword to the language, but it wouldn't help mu=
ch.
> >The existing usage of anything that evaluates to a constant integer 0
> >would still have to be allowed as a null pointer constant.
>
> Yes, but I think that it's good enough anyway.
>
> >The interactions of a 'null' keyword with the rest of the type system,
> >with templates, and as actual arguments to a variadic function are
> >not trivial to work out.
>
> Maybe we could just use a null-class as proposed here, then very little
> needs to be changed in the standard.
>
> >To make 'null' useful, we'd have to accept breaking most existing code
> >and make 'null' the only valid form of null pointer. (Possibly the
> >macro NULL could be redefined to be 'null',
>
> I think we should do like this:
> * Introduce a new keyword or a mandatory object of a null-class and
> call that "null", "nil" or something else than "NULL".
>
> * Say that NULL have to be defined as "null", "nil" or what it will be
> called.
>
> * Continue to support using a litteral zero as a null pointer, maybe
> require a warning and maybe consider it deprecated.
>
> >but that would still break all code that depended on the old
> >definition.
>
> * Make sure that the new definition of NULL never will cause silent
> changes, only errors when used wrong (assigning to integer, passing
> uncast to vararg etc.). Maybe we have to accept ONE possible silent
> change, the case of overloading pointers and integers (this does of
> couse not apply to C code).
Since this is completely implementable in C++ as it exists in the
current working paper, you can do it in your own code today. What
benefits arise from adding it to the language standard?
-- Pete
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "David R. Tribble" <david.tribble@central.beasys.com>
Date: 1997/01/09 Raw View
I originally wrote [In article 002c1f34@central.beasys.com]:
>>I've noticed a lot of machinations about how to devise a 'null' constant...
>>
>>Why not just add a 'null' keyword to the language and be done with it?
My intent was to stir up discussion about making it illegal to treat zero
as a special pointer value. That way, programmers would have to use the
'null' keyword when they needed a null pointer (assigning to pointers,
comparing to pointers, and passing pointers to functions). Like I've said
before, zero is an integer, dammit, not a pointer or a boolean. And a null
pointer is a pointer, dammit.
Yes, this would require changing the language. And yes, I know the ANSI
standard has been more or less cast in concrete for now. And yes, I know
this would break a few eggs.
But I would prefer that my language of choice be as semantically robust
and without holes as possible. Allowing zero to mean both (int)zero and
(pointer)null is a kludge and a hole. I'm sure many of you agree.
The rest of you probably don't care and probably think we're all wasting
time on a meaningless issue. You have missed the big picture: we want
C++ to be a good, robust language. We do not like to see kludges in our
language. Other languages (like Java, Pascal, Eiffel, and LISP) have
quite reasonable concepts of 'null'. Why not C++?
---
BTW, Stroustrup mentioned a possible solution, one that is probably
better than any mentioned to date:
A void* cannot be assigned to anything without a cast. Allowing
implicit conversions of void* to other pointer types would open a
serious hole in the type system. One might make a special case
for (void*)0, but special cases should only be admitted in dire need.
-- From D&E, p.230.
I like this idea. How do I love it? Let me count the ways:
1) 'NULL' could be a macro #defined to '((void*)0)', and could appear
in the standard header files (like it already does on most
implementations).
2) Compilers already know that '0' is a special null pointer, so
making them know instead that '(void*)0' is a null pointer shouldn't
be difficult.
3) You can't take the address of 'NULL'.
4) You can't declare objects of type 'NULL'.
5) 'NULL' isn't a class, so it doesn't interact with other areas of
the language or library in strange ways.
6) You can pass 'NULL' as an argument to a function.
7) It solves the overloaded function problem:
int func(int a);
int func(char *s);
...
x = func(NULL); // Calls only 'func(char*)'
8) It solves the variadic function problem:
int varfunc(int a, ...);
...
i = varfunc(3, "abc", NULL); // NULL is void*, not a class
9) I/O is properly defined for null pointers:
cout << NULL; // Output as a void*
...
cin >> cp; // Works, cp==NULL
printf("%p", NULL);
...
char * cp;
scanf("%p", &cp); // Works, cp==NULL
10) It's grep-able. And beginners aren't confused. And (most) old
programmers are already used to seeing 'NULL'.
11) There's no overhead.
Admittedly, the need for 'NULL' isn't dire; it's really an issue of
language esthetics.
________________________________________________________________________
David R. Tribble BEA Systems, Inc.
david.tribble@central.beasys.com Dallas, TX 75248
http://www.beasys.com +1-972-738-6125 Office
http://www.flash.net/~dtribble +1-972-738-6111 Fax
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Ted Clancy <s341282@student.uq.edu.au>
Date: 1997/01/09 Raw View
Ted Clancy wrote:
>
> Greg Comeau wrote:
> >
> > In article <199701030421.UAA10135@netcom5.netcom.com> Scott Meyers <smeyers@netcom.com> writes:
> > >A few months ago Ted Clancy proposed this for a non-int NULL:
> > >
> > >const class {
> > >public:
> > > template<class T> operator T*() const { return 0; }
> > >private:
> > > void operator&(); // disallow taking the address of NULL
> > >} NULL;
> > >
> > >This strikes me as a promising approach: NULL is not an int, and it's
> > >convertible to any type of pointer. Comments?
> >
> > Not any type.
> Yeah, but i don't think that's a major problem. Think of it as a
> pseudo-keyword, rather than an object. It would exist solely to be
> converted to other types for comparisons, initialisations, etc. It would
> not represent "nullness" on its own, or be passed to functions, etc.
>
> >
> > As mentioned, I believe this kind of thing seems to be where people need
> > to fiddle to address this. Some thoughts follow.
> >
> > This class does seem to address the common two raised points:
> >
> > * With Comeau C++, something such as:
> >
> > int i = NULL;
> >
> > produces:
> >
> > error: no suitable conversion function from "NULL" to "int" exists
> >
> > so that's good.
> >
> > * It certainly does distinguish between:
> >
> > void foo(int);
> > void foo(T*);
> >
> > without a problem.
> >
> > Some other things, continuing on both sides of the fence:
> >
> > * You still need a header file. Nothing lost, nothing gained, though you
> > do need to know the name of this one.
> >
> > * As well, you probably don't want to call this NULL so it enters the pool
> > of all the other names people have used over the years.
> > OTOH, you will NEVER escape typing NULL no matter how hard you try.
>
> I think it should be null in lowercase. Namespaces are meant to remove
> the problems you mention.
>
> > * You don't need <>'s so that's good.
> >
> > * W/o fiddling with the member template, this seem to be
> > a pointer-only thing at first glance, so that's good.
> > That is, it is ok with pointers to object and pointer to functions.
> >
> > * To get it ok with pointers to members perhaps you'll need a:
> >
> > template <class T, class C> operator T C::*() const { return 0; }
>
> Good idea.
>
> > * The case of something such as:
> >
> > char *pc = NULL;
> > if (NULL == pc)...
> >
> > is ok, though this is not:
> >
> > if (NULL == 0)...
>
> why would you be comparing 0 to the null constant? Why would you be
> comparing an integer against null instead of against 0?
>
> > and so perhaps an op void *() needs to specifically specialized.
> >
> > * Passing NULL to a variadic function is still a problem.
> > Is making a private NULL copy ctor enough for all cases?
> > (IOW, simply disallow it to be passed anywhere--
> > this is probably consistent along the lines of void *'ness.)
>
> Yeah, private copy constructor would be good. I don't think null should
> be allowed to be passed to a varargs function without being cast. The
> representation of a null object pointer might differ from a null
> function pointer, and probably differ from a null member pointer.
>
> > * You need to give the class a name, because you want diagnostics
> > to make sense (see the diagnostic above). However, this means that
> > now you can declare objects of NULL's. And you cannot make the ctor
> > private because then you cannot get the NULL object itself.
> > The same applies for making the NULL object const.
>
> I don't think we need to name it's class. Singleton objects of anonymous
> classes already exist. Sensible diagnostic messages are the
> responsibility of the compiler vendor.
>
> >
> > * An io capability may or may not be wise to add (probably not).
>
> Probably not. As I said, null-ness can have many different
> representaions depending on its type. It should be cast before being
> sent to an iostream.
>
> >
> > The pro sides of course may be fine for some. The above has no thought
> > whatsoever into deep dark pathological cases that no doubt exist.
> > Anybody have any? OTOH, there is probably some instrumentation goodies
> > one can get out of this if more is added. Just to recap, it seems we are
> > looking at something more like this:
> >
> > const class Null {
> > void operator&();
> > Null(const Null&);
> > public:
> > template <class T> operator T* () const { return 0; }
> > template <class T, class C> operator T C::*() const { return 0; }
> > operator void*() const { return 0; }
> >
> > friend ostream& operator<<(ostream& o, const Null& me)
> > { o << (void*)me; return o; } // if at all, assume void *?
> > void *value() const { return 0; } // of any use???
> > } Null;
> >
> The op<< seems redundant considering the conversion function to a void*,
> but I don't think there should be an op<< anyway.
>
> I'm not sure if there should be a op void*. Why should "null" be a void*
> before being any other type of pointer, considering the possibly
> different null representations, and remembering that a void* can no
> longer be implicitly cast to anything else. Can't see it would do any
> harm though.
>
> And value() has to be useless. Who would write null.value instead of 0?
>
> > - Greg
> >
> > --
> > Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
> > Producers of Comeau C++ 4.0 front-end pre-release
> > ****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
> > Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
>
> Thanks for testing the class (My compiler doesn't allow member templates
> -- I'm one of those broke undergrad students).
>
> I know that this is something which has been debated a long time, but
> it's also something which has been anoying me a long time (maybe I feel
> compelled for my language of choice to be universally better than
> Pascal, I don't know) and I think all the language elements we need to
> implement the solution are already in the draft.
>
> Updated idea:
>
> Ted Clancy
> s341282@student.uq.edu.au
> B Engineering, University of Queensland.
Whoops, I just realised a flaw in my idea. Having the null class
anonymous prevents defining a private copy constructor.
I believe this class anonymity is necessary to prevent instantiating
Null objects, or overloading functions on Null -- both of which I
believe cause more idiomatic problems than they solve)
I originally didn't think a private copy constructor was necessary
because I mistakenly thought passing a class object to a ... was
illegal, but it's merely undefined. My solution: Ditch the private copy
constructor (which wasn't in my original idea anyway) and make passing a
class object to a ... illegal (Oh no! a language change! but a good one)
or require it to give a warning.
//in standard namespace -- to prevent conflict with existing nulls
const class {
void operator&();
public:
template <class T> operator T* () const { return 0; }
template <class T, class C> operator T C::*() const { return 0; }
} null;
--
Ted Clancy | "...This is Pauline Hanson of
Borg
s341282@student.uq.edu.au | Resistance is futile
B Engineering, University of Queensland. | You _will_ be
assimilated..."
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/01/09 Raw View
Greg Comeau writes:
[about defining NULL as an instance of a class]
> * You need to give the class a name, because you want diagnostics
> to make sense (see the diagnostic above). However, this means that
> now you can declare objects of NULL's. And you cannot make the ctor
> private because then you cannot get the NULL object itself.
> The same applies for making the NULL object const.
NULL might be #defined to be ::std::Null::null, and Null::null would be a
static const instance of the class.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "David R. Tribble" <david.tribble@central.beasys.com>
Date: 1997/01/10 Raw View
Darron Shaffer wrote on passing NULL as an argument to a variadic
function:
>From: Darron.Shaffer@beasys.com (Darron Shaffer)
>Subject: Re: NULL pointer
>
>By the way, this will NOT work on one at least one current architecture:
>OSF/1 on the Alpha.
>
> C: (with NULL defined as "((void *) 0)")
>
> execl("text", "text", NULL); // 3 64-Bit args: char *, char *, void *
>
> C++: (with NULL defined as "0")
>
> execl("text", "text", NULL); // 2 64-Bit args: const char *, const char *
> // 1 32-Bit arg: int
>
>Oops, existing code just broke!
>
>(I haven't tried this, not having current access to an Alpha)
The implementors of the C compiler for the DEC Alpha were pretty clever
about dealing with intermixing 32-bit and 64-bit integers; both examples,
in fact, work correctly. This is because all integer (and pointer) args
are passed on the stack (or in registers) as 64-bit values.
This also explains why the following call works correctly (but is not
recommended for portability reasons):
printf("a=%d, b=%ld\n", 123L, 123);
(BTW, this brings up a few questions about POSIX data types.
Specifically, how big are uid_t, gid_t, pid_t, off_t, et al? If I have
to print them, do I use "%d" or "%ld"? This is not a problem on 32-bit
systems, but it can be on 64-bit CPUs. Personally, I always cast them to
long and use "%ld".)
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/10 Raw View
In article <rf5vi99vj5t.fsf@vx.cit.alcatel.fr> James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
>Note that according to the current draft, "When there is no parameter
>for a given argument, [...] if the argument has a non-POD class type,
>the behavior is undefined." Formally, this means that the library
>solution for NULL also results in undefined behavior.
At least one version of the NULL class presented was a POD.
Have I misunderstood your point?
> In practice, the
>compiler can easily determine this, and generate an error.
Determine what? That you passed a NULL object (in the lib version)?
> (Can anyone
>explain to me *WHY* this is undefined behavior, and not an error
>requiring a diagnostic?) (Note that the current situation results in an
>error that is impossible for the compiler to detect, and will work in
>most cases, so the error generally goes undetected. Even if the
>compiler doesn't detect the error with the library solution, it is
>highly unlikely that the resulting program will work. Also, I think
>that if the library solution adds a private copy constructor, it should
>give a diagnosible error in this case.)
It's certainly in the spirit of other similar rules.
Anyway, I never thought about this. I guess for cross language calls?
Baggage/mechanisms to support it can be provided but are not mandated?
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/10 Raw View
In article <32D1DD54.4990@student.uq.edu.au> Ted Clancy <s341282@student.uq.edu.au> writes:
>Greg Comeau wrote:
>>
>> In article <199701030421.UAA10135@netcom5.netcom.com> Scott Meyers <smeyers@netcom.com> writes:
>> >A few months ago Ted Clancy proposed this for a non-int NULL:
>> >
>> >const class {
>> >public:
>> > template<class T> operator T*() const { return 0; }
>> >private:
>> > void operator&(); // disallow taking the address of NULL
>> >} NULL;
>> >
>> >This strikes me as a promising approach: NULL is not an int, and it's
>> >convertible to any type of pointer. Comments?
>>
>> Not any type.
>Yeah, but i don't think that's a major problem. Think of it as a
>pseudo-keyword, rather than an object. It would exist solely to be
>converted to other types for comparisons, initialisations, etc. It would
>not represent "nullness" on its own, or be passed to functions, etc.
>
>>
>> As mentioned, I believe this kind of thing seems to be where people need
>> to fiddle to address this. Some thoughts follow.
>>
>> This class does seem to address the common two raised points:
>>
>> * With Comeau C++, something such as:
>>
>> int i = NULL;
>>
>> produces:
>>
>> error: no suitable conversion function from "NULL" to "int" exists
>>
>> so that's good.
>>
>> * It certainly does distinguish between:
>>
>> void foo(int);
>> void foo(T*);
>>
>> without a problem.
>>
>> Some other things, continuing on both sides of the fence:
>>
>> * You still need a header file. Nothing lost, nothing gained, though you
>> do need to know the name of this one.
>>
>> * As well, you probably don't want to call this NULL so it enters the pool
>> of all the other names people have used over the years.
>> OTOH, you will NEVER escape typing NULL no matter how hard you try.
>
>I think it should be null in lowercase. Namespaces are meant to remove
>the problems you mention.
>
>> * You don't need <>'s so that's good.
>>
>> * W/o fiddling with the member template, this seem to be
>> a pointer-only thing at first glance, so that's good.
>> That is, it is ok with pointers to object and pointer to functions.
>>
>> * To get it ok with pointers to members perhaps you'll need a:
>>
>> template <class T, class C> operator T C::*() const { return 0; }
>
>Good idea.
>
>> * The case of something such as:
>>
>> char *pc = NULL;
>> if (NULL == pc)...
>>
>> is ok, though this is not:
>>
>> if (NULL == 0)...
>>
>> and so perhaps an op void *() needs to specifically specialized.
>
>why would you be comparing 0 to the null constant? Why would you be
>comparing an integer against null instead of against 0?
Because it would be a pathological situation; because it is allowed now, etc.
Perhaps it might have been in a macro?
Mind you, I'm working from the premise that this is merely an exercise
(clearly it's not getting into the standard) and so what we have now
does not go away.
>> * Passing NULL to a variadic function is still a problem.
>> Is making a private NULL copy ctor enough for all cases?
>> (IOW, simply disallow it to be passed anywhere--
>> this is probably consistent along the lines of void *'ness.)
>
>Yeah, private copy constructor would be good. I don't think null should
>be allowed to be passed to a varargs function without being cast. The
>representation of a null object pointer might differ from a null
>function pointer, and probably differ from a null member pointer.
>
>> * You need to give the class a name, because you want diagnostics
>> to make sense (see the diagnostic above). However, this means that
>> now you can declare objects of NULL's. And you cannot make the ctor
>> private because then you cannot get the NULL object itself.
>> The same applies for making the NULL object const.
>
>I don't think we need to name it's class. Singleton objects of anonymous
>classes already exist. Sensible diagnostic messages are the
>responsibility of the compiler vendor.
The most sensible diagnostic would be if it were named.
Why should the compiler know the the heck this is?
Remember, this is a user class, nothing more.
>> * An io capability may or may not be wise to add (probably not).
>
>Probably not. As I said, null-ness can have many different
>representaions depending on its type. It should be cast before being
>sent to an iostream.
Hopefully it doesn't get sent to one. Anyway, the problem is
how do you force the cast?
>> The pro sides of course may be fine for some. The above has no thought
>> whatsoever into deep dark pathological cases that no doubt exist.
>> Anybody have any? OTOH, there is probably some instrumentation goodies
>> one can get out of this if more is added. Just to recap, it seems we are
>> looking at something more like this:
>>
>> const class Null {
>> void operator&();
>> Null(const Null&);
>> public:
>> template <class T> operator T* () const { return 0; }
>> template <class T, class C> operator T C::*() const { return 0; }
>> operator void*() const { return 0; }
>>
>> friend ostream& operator<<(ostream& o, const Null& me)
>> { o << (void*)me; return o; } // if at all, assume void *?
>> void *value() const { return 0; } // of any use???
>> } Null;
>>
>The op<< seems redundant considering the conversion function to a void*,
>but I don't think there should be an op<< anyway.
>
>I'm not sure if there should be a op void*. Why should "null" be a void*
>before being any other type of pointer, considering the possibly
>different null representations, and remembering that a void* can no
>longer be implicitly cast to anything else. Can't see it would do any
>harm though.
If it does no harm then it clearly does not belong. Above says
why it is there.
>And value() has to be useless. Who would write null.value instead of 0?
I put it there to see if it would spark something I may have missing.
Like I ask, of any use? Most likely not.
>
>> - Greg
>>
>> --
>> Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
>> Producers of Comeau C++ 4.0 front-end pre-release
>> ****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
>> Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
>
>Thanks for testing the class (My compiler doesn't allow member templates
>-- I'm one of those broke undergrad students).
Well, get your U to get one that does ;-)
>I know that this is something which has been debated a long time, but
>it's also something which has been anoying me a long time (maybe I feel
>compelled for my language of choice to be universally better than
>Pascal, I don't know) and I think all the language elements we need to
>implement the solution are already in the draft.
>
>Updated idea:
>const class {
> void operator&();
> Null(const Null&); //to prevent passing to functions
>public:
> template <class T> operator T* () const { return 0; }
> template <class T, class C> operator T C::*() const { return 0; }
>} null;
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/03 Raw View
In article <eg5xyEpfhS+C090yn@nada.kth.se> d96-mst@nada.kth.se (Mikael St ldal) writes:
>In article <5a1fc2$42t@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>>I think it's less an issue of it being sensible than this:
>>What real problems does it solve?
>
>You can no longer mix up the null-pointer with the integer zero.
No, this is not the case. That's exactly part of my point.
>Assume two functions with this prototypes:
>void f1(char*, long);
>void f2(int, long);
>
>{
> long l;
> char* c;
>
> // assign something l and c
>
> // let's call the function, I want zero for the int argument
> f1(0, l); // oops wrong function
>
> // let's call the other function, I want NULL for the char* argument
> f2(NULL, l*2); // oops wrong function
>}
>
>With the proposal, this defective code won't compile.
If I understand this example, you are trying to demonstrate how
NULL interacts with a mistyped function name? I tend to find
this a red herring because it is not the point at all.
If this is not the demonstration you intented, by all means clarify.
>But this is a silly example
Er, yes, see above comments.
>in C++ we use overloading and thing will
>work much better, wouldn't they?
Maybe. If it makes sense to overload. I mean, we don't just use
it because we can.
> Let's try:
>
>void f(char*, long);
>void f(int, long);
>
>{
> long l;
> char* c;
>
> f(0, l);
> f(NULL, l);
>}
>
>Works great, huh?
I find this another red herring because even independent of NULL (again)
I would probably find such an overload sample as suspect.
>It's really bad that C++ should be even worse than C in this case :-(
Perhaps this is an eye of the beholder issue, but the way I see it,
it's broken in C and C++ is trying as best it can with it.
Certainly the two examples above do not support this believe.
The first is the case in _either_ language. The second is
not supported in C at all and so definitely does not work great in C.
I hence remain unclear on your points.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/03 Raw View
In article <jc5xyEpfhm3M090yn@nada.kth.se> d96-mst@nada.kth.se (Mikael St ldal) writes:
>In article <5a1eq7$26g@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>>>#define NULL ((void*)0)
>>>
>>>This is how it use to be defined in C
>>
>>Maybe your compiler used to define it like this, but C certainly
>>never mandated it to do so.
>
>It's possible to define it like that in C, but currently not in C++ :-(
Given the situation, this then is a good thing for the standard to
support, not a bad one.
>>This begs for why using NULL gains little
>
>Right, using NULL gains little in C++ as today, my proposal would fix
>that.
>
>>In te long run, there is no perfect solution, but, if you'll excuse my
>>slang, maybe using the "keyword" 0 would help instead of using NULL?
>
>No. What I want is a symbol for null-pointer that CANNOT be used as an
>integer. That would make the type system stronger.
It would, but that alone would not be the end of the situation and
so as such the context of the benefit is not as strong as it make at
first seem.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Scott Meyers <smeyers@netcom.com>
Date: 1997/01/03 Raw View
A few months ago Ted Clancy proposed this for a non-int NULL:
const class {
public:
template<class T> operator T*() const { return 0; }
private:
void operator&(); // disallow taking the address of NULL
} NULL;
This strikes me as a promising approach: NULL is not an int, and it's
convertible to any type of pointer. Comments?
Scott
--
Scott Meyers, Ph.D. Voice: 503/638-6028
C++ Consulting and Training Fax: 503/638-6614
Author of "Effective C++" Email: smeyers@netcom.com
and "More Effective C++" WWW: http://www.teleport.com/~smeyers
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1997/01/03 Raw View
Chelly Green wrote:
>
> Mikael Steldal wrote:
> >
> > In article <5a1fc2$42t@panix.com>, comeau@panix.com (Greg Comeau) wrote:
> > >I think it's less an issue of it being sensible than this:
> > >What real problems does it solve?
> >
> > You can no longer mix up the null-pointer with the integer zero.
...
> > Assume two functions with this prototypes:
> > void f1(char*, long);
> > void f2(int, long);
>
> Meaningless. Give them real names and then tell me how obvious the
> errors below become.
...
> And you're saying this is the compiler's fault?!? It's yours for naming
> the functions with names so "close".
...
> > in C++ we use overloading and thing will
> > work much better, wouldn't they?
>
> Assuming the overloaded functions do the same thing. If they don't, then
> their names should not be the same (or even close, like the above f1 and
> f2).
>
> > Let's try:
> >
> > void f(char*, long);
> > void f(int, long);
>
> Well, what do they do? Do they convert the char string to a number (or
> vice versa)? Maybe using a real string here would help?
>
> > {
> > long l;
> > char* c;
> >
> > f(0, l);
> > f(NULL, l);
> > }
> >
> > Works great, huh?
>
> I guess I don't understand why one takes a pointer, and another a value.
It's pretty obvious from the original post that Mikael was intending
that f1(), f2(), and f() all represented conceptually similar functions;
otherwise it wouldn't make sense to overload them. That also explains
why he named them so similarly in the C version. Perhaps f("123", 1)
does the same thing as f(123,1). This problem is not unique to (char *)
variables; you get the same problem with (int *). I could easily imaging
two versions of a function taking either a single integer or an array of
integers. The details don't matter; what does matter is the loss of type
checking.
> Maybe if they took a pointer to char and pointer to int, you would get
> better results.
>
> > It's really bad that C++ should be even worse than C in this case :-(
>
> Excuse me, are you saying that your C++ compiler didn't accept the C
> version above? Or are you saying that C++ is worse because it offers
> more options?
C++ is better because it allows overloading, and worse because the
different definition of NULL defeats the automatic mechanism for
choosing which overloaded version to use.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/03 Raw View
In article <m3681kvxbn.fsf@gabi-soft.fr> kanze@gabi-soft.fr (J. Kanze) writes:
>comeau@panix.com (Greg Comeau) writes:
>
>> In article <59vgan$9bl@sjx-ixn10.ix.netcom.com> wkdugan@ix.netcom.com (Bill Dugan) writes:
>> >James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
>> >
>> >snip
>> >
>> >>This was proposed, in almost exactly the form you suggest. (I know. I
>> >>wrote the proposal.) It was rejected by the committee.
>> >
>> >What was their reason? It sounds like a sensible idea.
>>
>> I think it's less an issue of it being sensible than this:
>> What real problems does it solve?
>> What real problems does it leave unsolved?
>> How does it solve current problems better than the current situation
>> and/or other current solutions?
>
>I think that this was part of it. I was unable to attend the meeting
>where it was discussed, so I can only say from hearsay, but apparantly,
>part of the opposition was that it didn't buy us enough; some of the
>opponents wanted a real nil type.
I think this is a real wart, a source of endless debate, and
probably a source of confusion as well. But, we can kick and scream
all we want (not saying you are) but it just ain't gunna fly at this
point. Would it have flown earlier? No. Because this whole
"NULL thingie" has been debated even before C++ even existed.
In short, we would have had it already somehow. It simply comes
down to that it impacts too much and most proposals for "fixing"
it would not be complete and would complicate things even further.
I wouldn't mind a solution, whole and complete, on this issue,
but just know it's never going to happen. And I don't mean this
as in people don't care, or that the committees didn't think they
needed to worry about this, etc., but in that the problem is just
to inherent in the C heritage. It's simply not a perfect situation,
and neither are most alternatives.
Indeed then, I think it's fair to say then that the issue does
come down to a 6 of 1 vs 1/2 dozen of another in this case,
and so as that it's a matter of personal/shop style, personal/shop
preference and one's corner of the universe that they program in.
There is no winner here. Unfortunately.
You may argue that we got bool, and enum overloads, and other things,
for similar/related reasons, and obviously they got voted in, even
though they added new types, fixed certain problems, etc.
Sure, there is truth to this. However, that _alone_ cannot be sufficient
argument for modification in this area.
(James, I believe you'll have no general problem with these statements
but still felt I needed to state them as many don't put thought
into the full picture and tradesoffs and compromises of things,
especially when they appear trivial or rational at first glance).
>IMHO, the major problem was simple: if I'm dealing with pointers, I want
>the fact apparent, and want to use NULL, rather than 0. However, I most
>definitly don't want "f( NULL )" to call "f( int )".
Agreed that,the conceptualization and the potentials here just don't jive.
>An additional problem is that of matching types when using stdarg.
Yup.
> My
>proposal didn't do anything to address this; NULL had type void*, and if
>the called function expected a char*, the results were undefined. This
>could be solved by creating a new, special type for NULL; passing this
>type (uncast) as a variadic arg would then be an error.
Right, so we're on a path of doing a lot of work to cover ever
corner of this sucker, so it's unclear what the complexity
is gaining.
>I didn't opt for this second solution because I didn't feel variadic
>args are that important (in C++), introducing a new type has a major
>effect on the standard (think of template matching), my proposal was
>made very late in the game, and I wanted to keep the impact on the
>standard as limited as possible.
Good ;-)
> Globally, I think that the new type
>would be an even better solution, but it would have required
>significantly more work, and IMHO, also risked delaying the standard.
Agreed.
>If you do like the proposal, Fergus Henderson implemented it, or
>something very close to it, in g++. I think that current releases of
>g++ use either Fergus' implementation, or something similar, and that
>unless you specify -pendantic, "((void*)0)" works as a null pointer.
>(Since g++ normally picks up part of its headers from the local
>environment, I don't think that they can redefine NULL.)
We consider this a fundamental feature, so wouldn't want to have
any variation on our compiler offering except perhaps as a custom extension
only.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/03 Raw View
In article <rf5sp4kxtoz.fsf@vx.cit.alcatel.fr> James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
>d96-mst@nada.kth.se (Mikael St ldal) writes:
>
>|> In article <5a1eq7$26g@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>
>|> >In te long run, there is no perfect solution, but, if you'll excuse my
>|> >slang, maybe using the "keyword" 0 would help instead of using NULL?
>|>
>|> No. What I want is a symbol for null-pointer that CANNOT be used as an
>|> integer. That would make the type system stronger.
>
>IMHO, NULL certainly helps readability. This is an opinion, of course,
>and opinions may differ. Still, others who share my opinion include not
>only Pascal'ists like Nikolas Wirth, but people like Kernighan and
>Richie, who suggest using it to improve readability in "The C
>Programming Language". Strange as it seems, we seem to have found
>something on which both sides in the great C vs. Pascal argument agree.
IMO all NULL gains is grep'ability, but that's MO.
I think that NULL has caused so much debate and confusion for decades
now is testimony that its readability is one of the theory vs practice
misnomers.
>The problem with using 0 is that it is a major step backwards (with
>regards to C) in terms of software engineering.
I won't ask, so don't tell ;-)
> The problem with using
>NULL, as currently defined, is that it causes the wrong overloaded
>function to be called.
That problem, at least I believe, is not _the_ problem but a specific
effect of the whole monster. That is to say, I very much feel NULL
is not right even in K&R C.
>IMHO, there are (or rather, were) three possible courses of action:
>
>1. Maintain the status quo. It's not as bad as it seems; I, for one,
>cannot remember the last time I used a C-style pointer in application
>software, and of course, GB_RefCntPtr provides a const static data
>member, null:-).
There, see! ;-)
> The places were C-style pointers are necessary/useful
>are at such a low level, and involve enough other programming tricks,
>that the improvement in readability brought be NULL is negligible.
I would not state it that way but probably something along the lines
of s/improvement of readability/usability of/.
To me, although I want to buy the readibility argument, FIRST AND FOREMOST
is that NULL _must_ be a solid conceptualization to me. Surely I do
understand it, however, it just doesn't go the full mile on it for me.
This of course involves `null pointer' too.
>2. Require NULL to be defined as "static_cast< void* >( 0 )", and define
>the meta magic which currently breaks open the type system to work on
>"an integral expression evaluating to 0, cast to void*". This was
>basically my proposal. It solves the most obvious problem of using
>NULL: you can use it without having it call f( int ). It has the
>additional advantage of simplicity, since its effects on the standard
>are, I believe, very local. It still fails in cases of varidic
>arguments, and of course, if you have several overloaded functions which
>take pointers. (It calls the void* one, if it exists. Which may or may
>not be correct.)
This probably would cover the most obvious "damage control."
>3. Make NULL a new keyword (probably indirectly, through a macro), with
>a special type all its own. This is in many ways the ideal solution,
>since you can then also define that this type cannot match a ... when
>passing arguments. And since you cannot declare a function parameter
>with this type, if there is more than one function which takes a
>pointer, the call is ambiguous (as it should be) without an explicit
>cast. The major problem with this solution is the enormous impact it
>has on other parts of the standard; it introduces a totally new type,
>and so you really have to define what happens with this type everywhere
>types are relevant.
So the question is: how can the impact be avoided?
A "null" template library perhaps? A pointer class?
>At the time I made my proposal, I felt that it was already too late for
>solution 3. It would have introduced serious delays in the standard.
>At present, of course, it is also too later for solution 2.
>
>One thing just occurs to me: the C standard is currently entering
>revision, and solution 3 might appeal to them. On one hand, the varidic
>args problem occurs far more frequently in C than in C++ (and of course,
>NULL, rather than 0, is almost universally used in C), and on the other,
>without function overloading and templates, the impact is far less.
Actually, the C committee is wrapping up too.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Ted Clancy <s341282@student.uq.edu.au>
Date: 1997/01/05 Raw View
Scott Meyers wrote:
>
> A few months ago Ted Clancy proposed this for a non-int NULL:
>
> const class {
> public:
> template<class T> operator T*() const { return 0; }
> private:
> void operator&(); // disallow taking the address of NULL
> } NULL;
>
> This strikes me as a promising approach: NULL is not an int, and it's
> convertible to any type of pointer. Comments?
>
> Scott
>
> --
> Scott Meyers, Ph.D. Voice: 503/638-6028
> C++ Consulting and Training Fax: 503/638-6614
> Author of "Effective C++" Email: smeyers@netcom.com
> and "More Effective C++" WWW: http://www.teleport.com/~smeyers
>
Well, I'll comment that I like the idea, (but I thought of it, so of
course I like it). I'll just point out that it has the benefits of other
ideas presented here, but requires no changes to the language
specification, so it should be easy to add to the standard (maybe the
stl) without any side effects.
It is grep-able, it has no overhead (just include it in a header -- it's
a const, and all functions are inline), it is not a MACRO, and I think
it should solve the varargs problem (though I haven't been able to try
it out because my compiler doesn't support member templates).
As a further suggestion, perhaps it should be spelt "null" in
lower-case, just like the other standard library elements. That way,
NULL can remain a MACRO (which can be set to 0, or to the new "null"),
in accordance with the current standard (which states NULL should be a
MACRO), in order to please compiler vendors who don't support member
templates yet. People could start using the new "null" as the old MACRO
"NULL" is kept for compatibility, or phased out (as MACROs should be,
some would say).
As for people who don't think the null pointer is a problem worthy of
debate, even Bjarne Stroustrup in the D&E says he thinks the current
NULL is a problem, and it is unfortunate that C is more type-safe than
C++ in this respect. He just thought that there wasn't an easy solution.
(He didn't have member templates when he wrote that).
And I'd like to acknowledge the contribution of someone whose name I
can't remember but I have written down somewhere (Andrew something?). My
original suggestion had operator& return 0. He suggested making it void
and private.
--
Ted Clancy | "...This is Pauline Hanson of Borg
s341282@student.uq.edu.au | Resistance is futile
B Engineering, University of Queensland. | You _will_ be assimilated..."
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1997/01/05 Raw View
In article <rf5sp4kxtoz.fsf@vx.cit.alcatel.fr>,
James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
>IMHO, NULL certainly helps readability.
I do agree, and I always uses it even if it's simply #defined to 0. But
it would be even better if it also would enhance type-safety to use
NULL instead of 0.
>1. Maintain the status quo. It's not as bad as it seems; I, for one,
>cannot remember the last time I used a C-style pointer in application
>software,
It's probably very common when using C++ as "a better C", and IMHO
that's a sensible use for the language that should be supported in the
standard.
>2. Require NULL to be defined as "static_cast< void* >( 0 )",
That's would be very good since it would be similar to "(void*)0" that
is common C.
>It still fails in cases of varidic arguments, and of course, if you
>have several overloaded functions which take pointers.
But it's definitly better than nothing and IMHO good enough.
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1997/01/05 Raw View
In article <5ai5mf$r15@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>it's broken in C and C++ is trying as best it can with it.
It's not that broken in C.
>Certainly the two examples above do not support this believe.
>The first is the case in _either_ language.
No, in most C compilers it would generate a diagnostic, but not in any
C++ compiler I've tried (test it with GCC and G++).
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/06 Raw View
Ted Clancy <s341282@student.uq.edu.au> writes:
|> Scott Meyers wrote:
|> >
|> > A few months ago Ted Clancy proposed this for a non-int NULL:
|> >
|> > const class {
|> > public:
|> > template<class T> operator T*() const { return 0; }
|> > private:
|> > void operator&(); // disallow taking the address of NULL
|> > } NULL;
|> >
|> > This strikes me as a promising approach: NULL is not an int, and it's
|> > convertible to any type of pointer. Comments?
|>
|> Well, I'll comment that I like the idea, (but I thought of it, so of
|> course I like it). I'll just point out that it has the benefits of other
|> ideas presented here, but requires no changes to the language
|> specification, so it should be easy to add to the standard (maybe the
|> stl) without any side effects.
|>
|> It is grep-able, it has no overhead (just include it in a header -- it's
|> a const, and all functions are inline), it is not a MACRO, and I think
|> it should solve the varargs problem (though I haven't been able to try
|> it out because my compiler doesn't support member templates).
Is it legal to pass a class type to a vararg? If so, it will give
*VERY* unexpected results. (If so, IMHO, the standard should be changed
to forbid it. Except that there may be a question of C compatibility
involved; I think that you can pass a struct to a vararg in C. So we
end up with some strange and awkward rule concerning the presence or
absence of a destructor.)
|> As a further suggestion, perhaps it should be spelt "null" in
|> lower-case, just like the other standard library elements. That way,
|> NULL can remain a MACRO (which can be set to 0, or to the new "null"),
|> in accordance with the current standard (which states NULL should be a
|> MACRO), in order to please compiler vendors who don't support member
|> templates yet. People could start using the new "null" as the old MACRO
|> "NULL" is kept for compatibility, or phased out (as MACROs should be,
|> some would say).
Or should it be std::null? (I actually think that that is the best
solution.)
|> As for people who don't think the null pointer is a problem worthy of
|> debate, even Bjarne Stroustrup in the D&E says he thinks the current
|> NULL is a problem, and it is unfortunate that C is more type-safe than
|> C++ in this respect. He just thought that there wasn't an easy solution.
|> (He didn't have member templates when he wrote that).
I don't think that it is a question of people not thinking the question
worthy of debate, it is more a question of people who are tired of
hearing the debate. I've been hearing it for 5 years now. I'm not
totally (or even particularly) pleased with the current situation, but
there are more important issues (like getting the standard adopted).
--
James Kanze home: kanze@gabi-soft.fr +33 (0)3 88 14 49 00
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Nat Pryce <np2@doc.ic.ac.uk>
Date: 1997/01/06 Raw View
Mikael Steldal <d96-mst@nada.kth.se> wrote in article <jc5xyEpfhm3M090yn@nada.kth.se>...
> In article <5a1eq7$26g@panix.com>, comeau@panix.com (Greg Comeau) wrote:
> >In the long run, there is no perfect solution, but, if you'll excuse my
> >slang, maybe using the "keyword" 0 would help instead of using NULL?
>
> No. What I want is a symbol for null-pointer that CANNOT be used as an
> integer. That would make the type system stronger.
>
Why not define a NullPointer class with a const conversion operator to void*
which returns 0. You could have a global constant of type NullPointer
called "null" or whatever. This also has the advantage of allowing one to
define functions which are overridden for the NullPointer type.
With template member functions, you can (I believe) have a conversion
operator to T*, rather than just to void*, but my compiler does not yet
support this feature so I cannot check.
Here's what I mean...
class NullPointer
{
public:
template <class T> operator T*() const { return 0; }
template <class T> operator const T*() const { return 0; }
};
extern const NullPointer null;
And an example of overriding:
class SomeSmartPointer
{
public:
SomeSmartPointer( NullPointer );
SomeSmartPointer( SomeClass* );
...
};
Cheers,
Nat.
--
+-------------------------------------------+---------------------------------+
| Name: Nat Pryce MEng ACGI O- | Mail: Department of Computing, |
| Email: np2@doc.ic.ac.uk | Imperial College, |
| Tel: +44 (0)171 594 8394 (Direct Dial) | 180 Queen's Gate, |
| Fax: +44 (0)171 581 8024 | London SW7 2BZ, |
| WWW: http://www-dse.doc.ic.ac.uk/~np2 | United Kingdom |
+-------------------------------------------+---------------------------------+
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/06 Raw View
comeau@panix.com (Greg Comeau) writes:
[Concerning NULL in C++...]
|> You may argue that we got bool, and enum overloads, and other things,
|> for similar/related reasons, and obviously they got voted in, even
|> though they added new types, fixed certain problems, etc.
|> Sure, there is truth to this. However, that _alone_ cannot be sufficient
|> argument for modification in this area.
I think that the bool extension is significant. It is, in many ways,
similar to NULL. It is worth noting that the proposal is a decided
compromize: bool is an integral type, it converts freely to and from
other integral types, and even from floating point and pointer types.
It even supports the operation ++. (For historical reasons, so that
broken code which seems to work will still seem to work.)
Despite all of this, the proposal was weeked further by the committee.
In the original proposal, the implicit conversions were "deprecated", in
order to encourage compiler writers to generate a warning. IMHO, a good
compiler should still generate a warning, but I suspect that most
compiler writers are understandably more concerned with the general
market than with my humble opinion.
[...]
|> >If you do like the proposal, Fergus Henderson implemented it, or
|> >something very close to it, in g++. I think that current releases of
|> >g++ use either Fergus' implementation, or something similar, and that
|> >unless you specify -pendantic, "((void*)0)" works as a null pointer.
|> >(Since g++ normally picks up part of its headers from the local
|> >environment, I don't think that they can redefine NULL.)
|>
|> We consider this a fundamental feature, so wouldn't want to have
|> any variation on our compiler offering except perhaps as a custom extension
|> only.
I can well understand this point of view. On the other hand, if it is
offered as a pure extension, which requires an explicit switch to
activate, I think it is acceptable. Of course, given the portability
constraints of most of what I write, I couldn't use it if it were
there:-).
I'm not sure what the current policy of Cygnus is concerning g++; in the
past, they did have significant extensions (much larger than this) which
were active by default. (Personally, I don't really like extensions to
be active by default. Too many people seem to not realize that they are
using an extension, and then complain when their code doesn't compile
elsewhere.)
--
James Kanze home: kanze@gabi-soft.fr +33 (0)3 88 14 49 00
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
-- Conseils en informatique industrielle --
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "David R. Tribble" <david.tribble@central.beasys.com>
Date: 1997/01/06 Raw View
>>From: Scott Meyers <smeyers@netcom.com>
>>Newsgroups: comp.std.c++
>>Subject: Re: NULL pointer
>>Date: 3 Jan 1997 17:36:11 GMT
>>Approved: clamage@eng.sun.com (comp.std.c++)
>>Message-ID: <199701030421.UAA10135@netcom5.netcom.com>
>>
>>A few months ago Ted Clancy proposed this for a non-int NULL:
>>
>>const class {
>>public:
>> template<class T> operator T*() const { return 0; }
>>private:
>> void operator&(); // disallow taking the address of NULL
>>} NULL;
>>
>>This strikes me as a promising approach: NULL is not an int, and it's
>>convertible to any type of pointer. Comments?
>>
>>Scott Meyers, Ph.D.
I've noticed a lot of machinations about how to devise a 'null' constant
or type that works the way one would expect it to, i.e., it converts to
any pointer type, but isn't an int or bool. I agree with the need for
something explicit, because using '0' to mean 'null' is a ludicrous and
confusing kludge.
Why not just add a 'null' keyword to the language and be done with it?
________________________________________________________________________
David R. Tribble BEA Systems, Inc.
david.tribble@central.beasys.com Dallas, TX 75248
http://www.beasys.com +1-972-738-6125 Office
http://www.flash.net/~dtribble +1-972-738-6111 Fax
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "David R. Tribble" <david.tribble@central.beasys.com>
Date: 1997/01/06 Raw View
>Scott Meyers replies:
>
>>Why not just add a 'null' keyword to the language and be done with it?
>
>Because the standardization effort is bascially over and the language
>is frozen for at least 5 years.
That's too bad. And I know I'm not alone in this opinion.
It's not so bad using a type-safe workaround for 'NULL'. Like many good
programmers, I use NULL in all my pointer expressions, even though it's
currently only a preprocessor macro. Hopefully the workaround you posted
will become widespread soon.
What is disappointing, though, is the fact that '0' is still usable as a
pointer value. This is an atrocious kludge in the language, and leaves
some semantic holes open:
Class Foo
{
public:
int func(char *ptr);
int func(int val);
int func(bool flag);
};
... x = f.func(NULL); // Should be only func(char *)
... x = f.func(0); // Which func() ?
I've said it before, and I'll say it again:
Zero is an integer, dammit, not a pointer or boolean.
________________________________________________________________________
David R. Tribble BEA Systems, Inc.
david.tribble@central.beasys.com Dallas, TX 75248
http://www.beasys.com +1-972-738-6125 Office
http://www.flash.net/~dtribble +1-972-738-6111 Fax
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Roger L. Cauvin" <rcauvin@homemail.com>
Date: 1997/01/06 Raw View
James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote in article
<rf5d8vj6nbk.fsf@vx.cit.alcatel.fr>...
>
> I think that the bool extension is significant. It is, in many ways,
> similar to NULL. It is worth noting that the proposal is a decided
> compromize: bool is an integral type, it converts freely to and from
> other integral types, and even from floating point and pointer types.
> It even supports the operation ++. (For historical reasons, so that
> broken code which seems to work will still seem to work.)
>
> Despite all of this, the proposal was weeked further by the committee.
> In the original proposal, the implicit conversions were "deprecated", in
> order to encourage compiler writers to generate a warning. IMHO, a good
> compiler should still generate a warning, but I suspect that most
> compiler writers are understandably more concerned with the general
> market than with my humble opinion.
Just curious - was an implicit conversion from integer to bool considered
deprecated in the original proposal? E.g.
int i = 0;
if (!i) ... <---- deprecated?
How about pointer to bool comparisons? E.g.
int *p = NULL;
if (!p) ... <---- deprecated?
---
Roger L. Cauvin
rcauvin@homemail.com
Software Engineer
National Instruments
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Jason Merrill <jason@cygnus.com>
Date: 1997/01/06 Raw View
> In article <m3681kvxbn.fsf@gabi-soft.fr> kanze@gabi-soft.fr (J. Kanze) writes:
>> If you do like the proposal, Fergus Henderson implemented it, or
>> something very close to it, in g++. I think that current releases of
>> g++ use either Fergus' implementation, or something similar, and that
>> unless you specify -pendantic, "((void*)0)" works as a null pointer.
Actually, it wasn't Fergus, it was me. 2.7.2 treats ((void*)0) as a null
pointer constant regardless of -pedantic. 2.8 will use __null, a magic
null pointer constant of type void* by default, or the integer type with
the same size as void*, if -pedantic. ((void*)0) will no longer be a null
pointer constant.
>> (Since g++ normally picks up part of its headers from the local
>> environment, I don't think that they can redefine NULL.)
Actually, stddef.h is provided by gcc, so we redefine it there. We
could also tweak the definition in the system headers, but currently don't.
Jason
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/06 Raw View
In article <32CEF69C.2A93@student.uq.edu.au> Ted Clancy <s341282@student.uq.edu.au> writes:
>Scott Meyers wrote:
>>
>> A few months ago Ted Clancy proposed this for a non-int NULL:
>>
>> const class {
>> public:
>> template<class T> operator T*() const { return 0; }
>> private:
>> void operator&(); // disallow taking the address of NULL
>> } NULL;
>>
>> This strikes me as a promising approach: NULL is not an int, and it's
>> convertible to any type of pointer. Comments?
>>
>> Scott
>>
>> --
>> Scott Meyers, Ph.D. Voice: 503/638-6028
>> C++ Consulting and Training Fax: 503/638-6614
>> Author of "Effective C++" Email: smeyers@netcom.com
>> and "More Effective C++" WWW: http://www.teleport.com/~smeyers
>>
>Well, I'll comment that I like the idea, (but I thought of it, so of
>course I like it). I'll just point out that it has the benefits of other
>ideas presented here, but requires no changes to the language
>specification, so it should be easy to add to the standard (maybe the
>stl) without any side effects.
>
>It is grep-able, it has no overhead (just include it in a header -- it's
>a const, and all functions are inline), it is not a MACRO, and I think
>it should solve the varargs problem (though I haven't been able to try
>it out because my compiler doesn't support member templates).
How? That is, how would you va_arg it into the respective pointer
on the other side w/o anything extra or different in the user code?
>As a further suggestion, perhaps it should be spelt "null" in
>lower-case, just like the other standard library elements. That way,
>NULL can remain a MACRO (which can be set to 0, or to the new "null"),
>in accordance with the current standard (which states NULL should be a
>MACRO), in order to please compiler vendors who don't support member
>templates yet. People could start using the new "null" as the old MACRO
>"NULL" is kept for compatibility, or phased out (as MACROs should be,
>some would say).
NULL would always need to exist, always remain confusing to people,
and even with a perfect alternative (which would be great don't get me wrong)
people would still at least type NULL even if they didn't want to.
If this class makes sense, I believe it would have to be called something
totally different.
>As for people who don't think the null pointer is a problem worthy of
>debate, even Bjarne Stroustrup in the D&E says he thinks the current
>NULL is a problem, and it is unfortunate that C is more type-safe than
>C++ in this respect. He just thought that there wasn't an easy solution.
>(He didn't have member templates when he wrote that).
I don't believe he says it is unfortunate that C is more type-safe.
If anything he acknowledges it is a problem in both languages.
As well, he mentions that the 0 alternative is usually satisfactory.
Anyway, that's my interpretation and don't want to dwell on just this point.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/06 Raw View
In article <dC/zyEpfhmQL090yn@nada.kth.se> d96-mst@nada.kth.se (Mikael St ldal) writes:
>In article <5ai5mf$r15@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>>it's broken in C and C++ is trying as best it can with it.
>
>It's not that broken in C.
We'll have to agree to disagree.
I hope you at least agree that NULL has lived a life of debate and discussion.
>>Certainly the two examples above do not support this believe.
>>The first is the case in _either_ language.
>
>No, in most C compilers it would generate a diagnostic, but not in any
>C++ compiler I've tried (test it with GCC and G++).
What would? The two examples?
If I recall, one was function overloading, which would for sure
should emit an error in C. The other was different function names, so
I don't see it would be possible to diagnose this in C nor what the message
would say????
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/06 Raw View
In article <199701030421.UAA10135@netcom5.netcom.com> Scott Meyers <smeyers@netcom.com> writes:
>A few months ago Ted Clancy proposed this for a non-int NULL:
>
>const class {
>public:
> template<class T> operator T*() const { return 0; }
>private:
> void operator&(); // disallow taking the address of NULL
>} NULL;
>
>This strikes me as a promising approach: NULL is not an int, and it's
>convertible to any type of pointer. Comments?
Not any type.
As mentioned, I believe this kind of thing seems to be where people need
to fiddle to address this. Some thoughts follow.
This class does seem to address the common two raised points:
* With Comeau C++, something such as:
int i = NULL;
produces:
error: no suitable conversion function from "NULL" to "int" exists
so that's good.
* It certainly does distinguish between:
void foo(int);
void foo(T*);
without a problem.
Some other things, continuing on both sides of the fence:
* You still need a header file. Nothing lost, nothing gained, though you
do need to know the name of this one.
* As well, you probably don't want to call this NULL so it enters the pool
of all the other names people have used over the years.
OTOH, you will NEVER escape typing NULL no matter how hard you try.
* You don't need <>'s so that's good.
* W/o fiddling with the member template, this seem to be
a pointer-only thing at first glance, so that's good.
That is, it is ok with pointers to object and pointer to functions.
* To get it ok with pointers to members perhaps you'll need a:
template <class T, class C> operator T C::*() const { return 0; }
* The case of something such as:
char *pc = NULL;
if (NULL == pc)...
is ok, though this is not:
if (NULL == 0)...
and so perhaps an op void *() needs to specifically specialized.
* Passing NULL to a variadic function is still a problem.
Is making a private NULL copy ctor enough for all cases?
(IOW, simply disallow it to be passed anywhere--
this is probably consistent along the lines of void *'ness.)
* You need to give the class a name, because you want diagnostics
to make sense (see the diagnostic above). However, this means that
now you can declare objects of NULL's. And you cannot make the ctor
private because then you cannot get the NULL object itself.
The same applies for making the NULL object const.
* An io capability may or may not be wise to add (probably not).
The pro sides of course may be fine for some. The above has no thought
whatsoever into deep dark pathological cases that no doubt exist.
Anybody have any? OTOH, there is probably some instrumentation goodies
one can get out of this if more is added. Just to recap, it seems we are
looking at something more like this:
const class Null {
void operator&();
Null(const Null&);
public:
template <class T> operator T* () const { return 0; }
template <class T, class C> operator T C::*() const { return 0; }
operator void*() const { return 0; }
friend ostream& operator<<(ostream& o, const Null& me)
{ o << (void*)me; return o; } // if at all, assume void *?
void *value() const { return 0; } // of any use???
} Null;
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Ted Clancy <s341282@student.uq.edu.au>
Date: 1997/01/07 Raw View
Greg Comeau wrote:
>
> In article <32CEF69C.2A93@student.uq.edu.au> Ted Clancy <s341282@student.uq.edu.au> writes:
> >Scott Meyers wrote:
> >>
> >> A few months ago Ted Clancy proposed this for a non-int NULL:
> >>
> >> const class {
> >> public:
> >> template<class T> operator T*() const { return 0; }
> >> private:
> >> void operator&(); // disallow taking the address of NULL
> >> } NULL;
> >>
> >> This strikes me as a promising approach: NULL is not an int, and it's
> >> convertible to any type of pointer. Comments?
> >>
> >> Scott
> >>
> >> --
> >> Scott Meyers, Ph.D. Voice: 503/638-6028
> >> C++ Consulting and Training Fax: 503/638-6614
> >> Author of "Effective C++" Email: smeyers@netcom.com
> >> and "More Effective C++" WWW: http://www.teleport.com/~smeyers
> >>
> >Well, I'll comment that I like the idea, (but I thought of it, so of
> >course I like it). I'll just point out that it has the benefits of other
> >ideas presented here, but requires no changes to the language
> >specification, so it should be easy to add to the standard (maybe the
> >stl) without any side effects.
> >
> >It is grep-able, it has no overhead (just include it in a header -- it's
> >a const, and all functions are inline), it is not a MACRO, and I think
> >it should solve the varargs problem (though I haven't been able to try
> >it out because my compiler doesn't support member templates).
>
> How? That is, how would you va_arg it into the respective pointer
> on the other side w/o anything extra or different in the user code?
I don't think null should be allowed to be passed to a varargs without
being cast. The representation for a null function pointer might be
different to a null data pointer, and most probably different to a null
member pointer.
It has been suggested that classes should not be allowed to be passed to
varadic argument functions (with exceptions for simple structs), which I
agree with. If that becomes part of the standard, having "null" being a
class object prevents it being passed to such a function without being
cast.
>
> >As a further suggestion, perhaps it should be spelt "null" in
> >lower-case, just like the other standard library elements. That way,
> >NULL can remain a MACRO (which can be set to 0, or to the new "null"),
> >in accordance with the current standard (which states NULL should be a
> >MACRO), in order to please compiler vendors who don't support member
> >templates yet. People could start using the new "null" as the old MACRO
> >"NULL" is kept for compatibility, or phased out (as MACROs should be,
> >some would say).
>
> NULL would always need to exist, always remain confusing to people,
> and even with a perfect alternative (which would be great don't get me wrong)
> people would still at least type NULL even if they didn't want to.
> If this class makes sense, I believe it would have to be called something
> totally different.
>
> >As for people who don't think the null pointer is a problem worthy of
> >debate, even Bjarne Stroustrup in the D&E says he thinks the current
> >NULL is a problem, and it is unfortunate that C is more type-safe than
> >C++ in this respect. He just thought that there wasn't an easy solution.
> >(He didn't have member templates when he wrote that).
>
> I don't believe he says it is unfortunate that C is more type-safe.
> If anything he acknowledges it is a problem in both languages.
> As well, he mentions that the 0 alternative is usually satisfactory.
> Anyway, that's my interpretation and don't want to dwell on just this point.
>
> - Greg
> --
> Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
> Producers of Comeau C++ 4.0 front-end pre-release
> ****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
> Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
>
Ted Clancy
s341282@student.uq.edu.au
B Engineering, University of Queensland.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: stephen.clamage@Eng.Sun.COM (Steve Clamage)
Date: 1997/01/07 Raw View
In article 002c1f34@central.beasys.com, "David R. Tribble" <david.tribble@central.beasys.com> writes:
>
>I've noticed a lot of machinations about how to devise a 'null' constant ...
>
>Why not just add a 'null' keyword to the language and be done with it?
We could add a 'null' keyword to the language, but it wouldn't help much.
The existing usage of anything that evaluates to a constant integer 0
would still have to be allowed as a null pointer constant. Otherwise,
you break most existing programs, apart from introducing yet another
incompatibility with C.
The interactions of a 'null' keyword with the rest of the type system,
with templates, and as actual arguments to a variadic function are
not trivial to work out. Getting them wrong would make things worse.
Going to that much trouble would require a substantial payoff. IMHO,
an optional, additional way to specify a null pointer is not much of
a payoff.
To make 'null' useful, we'd have to accept breaking most existing code
and make 'null' the only valid form of null pointer. (Possibly the
macro NULL could be redefined to be 'null', but that would still break
all code that depended on the old definition. Usually it is better to
remove or make invalid an old construct instead of giving it a different
meaning. It avoids silent changes to programs.)
FWIW, I favor 'nil' as the keyword. It's less likely to cause confusion
with NULL and the ascii value NUL.
---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Ted Clancy <s341282@student.uq.edu.au>
Date: 1997/01/07 Raw View
Greg Comeau wrote:
>
> In article <199701030421.UAA10135@netcom5.netcom.com> Scott Meyers <smeyers@netcom.com> writes:
> >A few months ago Ted Clancy proposed this for a non-int NULL:
> >
> >const class {
> >public:
> > template<class T> operator T*() const { return 0; }
> >private:
> > void operator&(); // disallow taking the address of NULL
> >} NULL;
> >
> >This strikes me as a promising approach: NULL is not an int, and it's
> >convertible to any type of pointer. Comments?
>
> Not any type.
Yeah, but i don't think that's a major problem. Think of it as a
pseudo-keyword, rather than an object. It would exist solely to be
converted to other types for comparisons, initialisations, etc. It would
not represent "nullness" on its own, or be passed to functions, etc.
>
> As mentioned, I believe this kind of thing seems to be where people need
> to fiddle to address this. Some thoughts follow.
>
> This class does seem to address the common two raised points:
>
> * With Comeau C++, something such as:
>
> int i = NULL;
>
> produces:
>
> error: no suitable conversion function from "NULL" to "int" exists
>
> so that's good.
>
> * It certainly does distinguish between:
>
> void foo(int);
> void foo(T*);
>
> without a problem.
>
> Some other things, continuing on both sides of the fence:
>
> * You still need a header file. Nothing lost, nothing gained, though you
> do need to know the name of this one.
>
> * As well, you probably don't want to call this NULL so it enters the pool
> of all the other names people have used over the years.
> OTOH, you will NEVER escape typing NULL no matter how hard you try.
I think it should be null in lowercase. Namespaces are meant to remove
the problems you mention.
> * You don't need <>'s so that's good.
>
> * W/o fiddling with the member template, this seem to be
> a pointer-only thing at first glance, so that's good.
> That is, it is ok with pointers to object and pointer to functions.
>
> * To get it ok with pointers to members perhaps you'll need a:
>
> template <class T, class C> operator T C::*() const { return 0; }
Good idea.
> * The case of something such as:
>
> char *pc = NULL;
> if (NULL == pc)...
>
> is ok, though this is not:
>
> if (NULL == 0)...
why would you be comparing 0 to the null constant? Why would you be
comparing an integer against null instead of against 0?
> and so perhaps an op void *() needs to specifically specialized.
>
> * Passing NULL to a variadic function is still a problem.
> Is making a private NULL copy ctor enough for all cases?
> (IOW, simply disallow it to be passed anywhere--
> this is probably consistent along the lines of void *'ness.)
Yeah, private copy constructor would be good. I don't think null should
be allowed to be passed to a varargs function without being cast. The
representation of a null object pointer might differ from a null
function pointer, and probably differ from a null member pointer.
> * You need to give the class a name, because you want diagnostics
> to make sense (see the diagnostic above). However, this means that
> now you can declare objects of NULL's. And you cannot make the ctor
> private because then you cannot get the NULL object itself.
> The same applies for making the NULL object const.
I don't think we need to name it's class. Singleton objects of anonymous
classes already exist. Sensible diagnostic messages are the
responsibility of the compiler vendor.
>
> * An io capability may or may not be wise to add (probably not).
Probably not. As I said, null-ness can have many different
representaions depending on its type. It should be cast before being
sent to an iostream.
>
> The pro sides of course may be fine for some. The above has no thought
> whatsoever into deep dark pathological cases that no doubt exist.
> Anybody have any? OTOH, there is probably some instrumentation goodies
> one can get out of this if more is added. Just to recap, it seems we are
> looking at something more like this:
>
> const class Null {
> void operator&();
> Null(const Null&);
> public:
> template <class T> operator T* () const { return 0; }
> template <class T, class C> operator T C::*() const { return 0; }
> operator void*() const { return 0; }
>
> friend ostream& operator<<(ostream& o, const Null& me)
> { o << (void*)me; return o; } // if at all, assume void *?
> void *value() const { return 0; } // of any use???
> } Null;
>
The op<< seems redundant considering the conversion function to a void*,
but I don't think there should be an op<< anyway.
I'm not sure if there should be a op void*. Why should "null" be a void*
before being any other type of pointer, considering the possibly
different null representations, and remembering that a void* can no
longer be implicitly cast to anything else. Can't see it would do any
harm though.
And value() has to be useless. Who would write null.value instead of 0?
> - Greg
>
> --
> Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
> Producers of Comeau C++ 4.0 front-end pre-release
> ****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
> Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
Thanks for testing the class (My compiler doesn't allow member templates
-- I'm one of those broke undergrad students).
I know that this is something which has been debated a long time, but
it's also something which has been anoying me a long time (maybe I feel
compelled for my language of choice to be universally better than
Pascal, I don't know) and I think all the language elements we need to
implement the solution are already in the draft.
Updated idea:
const class {
void operator&();
Null(const Null&); //to prevent passing to functions
public:
template <class T> operator T* () const { return 0; }
template <class T, class C> operator T C::*() const { return 0; }
} null;
Ted Clancy
s341282@student.uq.edu.au
B Engineering, University of Queensland.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/07 Raw View
In article <01bbfbe4$5a75de90$490ea992@shub-niggurath> Nat Pryce <np2@doc.ic.ac.uk> writes:
>Mikael Steldal <d96-mst@nada.kth.se> wrote in article <jc5xyEpfhm3M090yn@nada.kth.se>...
>> In article <5a1eq7$26g@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>> >In the long run, there is no perfect solution, but, if you'll excuse my
>> >slang, maybe using the "keyword" 0 would help instead of using NULL?
>>
>> No. What I want is a symbol for null-pointer that CANNOT be used as an
>> integer. That would make the type system stronger.
>>
>
>Why not define a NullPointer class with a const conversion operator to void*
>which returns 0. You could have a global constant of type NullPointer
>called "null" or whatever. This also has the advantage of allowing one to
>define functions which are overridden for the NullPointer type.
>
>With template member functions, you can (I believe) have a conversion
>operator to T*, rather than just to void*, but my compiler does not yet
>support this feature so I cannot check.
>
>Here's what I mean...
>
>class NullPointer
>{
>public:
> template <class T> operator T*() const { return 0; }
> template <class T> operator const T*() const { return 0; }
You would not need the const T* because it would match the T* template
already. See other posts for more ideas on this.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/07 Raw View
"David R. Tribble" <david.tribble@central.beasys.com> writes:
|> Why not just add a 'null' keyword to the language and be done with it?
Because it isn't that simple. What is the type of `null'? If it is
void*, we really haven't gained much with regards to "((void*)0)". If
it has a new type, all its own, we have to define how this type behaves
in all situations where types are relevant (e.g.: template
instantiation).
--
James Kanze home: kanze@gabi-soft.fr +33 (0)3 88 14 49 00
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/07 Raw View
comeau@panix.com (Greg Comeau) writes:
|> In article <32CEF69C.2A93@student.uq.edu.au> Ted Clancy <s341282@student.uq.edu.au> writes:
[Concerning a library solution for null...]
|> >It is grep-able, it has no overhead (just include it in a header -- it's
|> >a const, and all functions are inline), it is not a MACRO, and I think
|> >it should solve the varargs problem (though I haven't been able to try
|> >it out because my compiler doesn't support member templates).
|>
|> How? That is, how would you va_arg it into the respective pointer
|> on the other side w/o anything extra or different in the user code?
It would solve the va_arg problem in that any attempt to pass null/NULL
to a ... would generate a compiler error.
This is, in fact, the best we can hope for. There is no way for the
compiler to determine the type that the callee will use to extract the
pointer. (Consider "printf( "abc" , NULL )".) So in practice, just
NULL is/should be an error. The user *MUST* specify what he wants.
The problem today is that NULL isn't an error. To take a classical
example from the Unix kernal interface:
execl( "/bin/someProgram" , "someProgram" , NULL ) ;
This is supposed to replace the current process with the program in file
"/bin/someProgram", with argv[ 0 ] == "someProgram", and argc == 1. In
fact, it is undefined behavior! It will, however, work on a great many
implementations, so the error is likely to go unnoticed for quite some
time. (Actually, given that code like this exists in so many Unix
applications, I suspect that any real implementation will do whatever is
necessary to make it work. Proving the customer wrong has never been a
particularly effective sales technique.)
FWIW: in the case of execl, *ALL* of the va_args must have type char
const*. Any other type (except maybe char*) is undefined behavior.
Note that according to the current draft, "When there is no parameter
for a given argument, [...] if the argument has a non-POD class type,
the behavior is undefined." Formally, this means that the library
solution for NULL also results in undefined behavior. In practice, the
compiler can easily determine this, and generate an error. (Can anyone
explain to me *WHY* this is undefined behavior, and not an error
requiring a diagnostic?) (Note that the current situation results in an
error that is impossible for the compiler to detect, and will work in
most cases, so the error generally goes undetected. Even if the
compiler doesn't detect the error with the library solution, it is
highly unlikely that the resulting program will work. Also, I think
that if the library solution adds a private copy constructor, it should
give a diagnosible error in this case.)
--
James Kanze home: kanze@gabi-soft.fr +33 (0)3 88 14 49 00
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Michael Hudson <sorry.no.email@nowhere.com>
Date: 1997/01/07 Raw View
David R. Tribble wrote:
> What is disappointing, though, is the fact that '0' is still usable as
> a pointer value. This is an atrocious kludge in the language, and
> leaves some semantic holes open:
The old excuse for many of the nasty things in C++ is C.
And, lets face it, the conversion of 0 implicitly to a pointer type has
been around for so long that changing it would be mighty painful.
>
> I've said it before, and I'll say it again:
> Zero is an integer, dammit, not a pointer or boolean.
>
You're right, though.
--
Regards,
Michael Hudson
Please don't email this address - it's not mine.
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Darron.Shaffer@beasys.com (Darron Shaffer)
Date: 1997/01/07 Raw View
>The problem today is that NULL isn't an error. To take a classical
>example from the Unix kernal interface:
>
> execl( "/bin/someProgram" , "someProgram" , NULL ) ;
>
>This is supposed to replace the current process with the program in file
>"/bin/someProgram", with argv[ 0 ] == "someProgram", and argc == 1. In
>fact, it is undefined behavior! It will, however, work on a great many
>implementations, so the error is likely to go unnoticed for quite some
>time. (Actually, given that code like this exists in so many Unix
>applications, I suspect that any real implementation will do whatever is
>necessary to make it work. Proving the customer wrong has never been a
>particularly effective sales technique.)
>
By the way, this will NOT work on one at least one current architecture:
OSF/1 on the Alpha.
C: (with NULL defined as "((void *) 0)")
execl("text", "text", NULL); // 3 64-Bit args: char *, char *, void *
C++: (with NULL defined as "0")
execl("text", "text", NULL); // 2 64-Bit args: const char *, const char *
// 1 32-Bit arg: int
Oops, existing code just broke!
(I haven't tried this, not having current access to an Alpha)
--
Darron Shaffer
Darron.Shaffer@beasys.com
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1996/12/30 Raw View
In article <5a1fc2$42t@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>I think it's less an issue of it being sensible than this:
>What real problems does it solve?
You can no longer mix up the null-pointer with the integer zero.
Assume two functions with this prototypes:
void f1(char*, long);
void f2(int, long);
{
long l;
char* c;
// assign something l and c
// let's call the function, I want zero for the int argument
f1(0, l); // oops wrong function
// let's call the other function, I want NULL for the char* argument
f2(NULL, l*2); // oops wrong function
}
With the proposal, this defective code won't compile.
But this is a silly example, in C++ we use overloading and thing will
work much better, wouldn't they? Let's try:
void f(char*, long);
void f(int, long);
{
long l;
char* c;
f(0, l);
f(NULL, l);
}
Works great, huh?
It's really bad that C++ should be even worse than C in this case :-(
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1996/12/31 Raw View
In article <5a1eq7$26g@panix.com>, comeau@panix.com (Greg Comeau) wrote:
>>#define NULL ((void*)0)
>>
>>This is how it use to be defined in C
>
>Maybe your compiler used to define it like this, but C certainly
>never mandated it to do so.
It's possible to define it like that in C, but currently not in C++ :-(
>This begs for why using NULL gains little
Right, using NULL gains little in C++ as today, my proposal would fix
that.
>In te long run, there is no perfect solution, but, if you'll excuse my
>slang, maybe using the "keyword" 0 would help instead of using NULL?
No. What I want is a symbol for null-pointer that CANNOT be used as an
integer. That would make the type system stronger.
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/01/02 Raw View
d96-mst@nada.kth.se (Mikael St ldal) writes:
|> In article <5a1eq7$26g@panix.com>, comeau@panix.com (Greg Comeau) wrote:
|> >In te long run, there is no perfect solution, but, if you'll excuse my
|> >slang, maybe using the "keyword" 0 would help instead of using NULL?
|>
|> No. What I want is a symbol for null-pointer that CANNOT be used as an
|> integer. That would make the type system stronger.
IMHO, NULL certainly helps readability. This is an opinion, of course,
and opinions may differ. Still, others who share my opinion include not
only Pascal'ists like Nikolas Wirth, but people like Kernighan and
Richie, who suggest using it to improve readability in "The C
Programming Language". Strange as it seems, we seem to have found
something on which both sides in the great C vs. Pascal argument agree.
The problem with using 0 is that it is a major step backwards (with
regards to C) in terms of software engineering. The problem with using
NULL, as currently defined, is that it causes the wrong overloaded
function to be called.
IMHO, there are (or rather, were) three possible courses of action:
1. Maintain the status quo. It's not as bad as it seems; I, for one,
cannot remember the last time I used a C-style pointer in application
software, and of course, GB_RefCntPtr provides a const static data
member, null:-). The places were C-style pointers are necessary/useful
are at such a low level, and involve enough other programming tricks,
that the improvement in readability brought be NULL is negligible.
2. Require NULL to be defined as "static_cast< void* >( 0 )", and define
the meta magic which currently breaks open the type system to work on
"an integral expression evaluating to 0, cast to void*". This was
basically my proposal. It solves the most obvious problem of using
NULL: you can use it without having it call f( int ). It has the
additional advantage of simplicity, since its effects on the standard
are, I believe, very local. It still fails in cases of varidic
arguments, and of course, if you have several overloaded functions which
take pointers. (It calls the void* one, if it exists. Which may or may
not be correct.)
3. Make NULL a new keyword (probably indirectly, through a macro), with
a special type all its own. This is in many ways the ideal solution,
since you can then also define that this type cannot match a ... when
passing arguments. And since you cannot declare a function parameter
with this type, if there is more than one function which takes a
pointer, the call is ambiguous (as it should be) without an explicit
cast. The major problem with this solution is the enormous impact it
has on other parts of the standard; it introduces a totally new type,
and so you really have to define what happens with this type everywhere
types are relevant.
At the time I made my proposal, I felt that it was already too late for
solution 3. It would have introduced serious delays in the standard.
At present, of course, it is also too later for solution 2.
One thing just occurs to me: the C standard is currently entering
revision, and solution 3 might appeal to them. On one hand, the varidic
args problem occurs far more frequently in C than in C++ (and of course,
NULL, rather than 0, is almost universally used in C), and on the other,
without function overloading and templates, the impact is far less.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)3 88 14 49 00
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
-- Conseils en informatique industrielle --
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Chelly Green <chelly@eden.com>
Date: 1997/01/02 Raw View
Mikael St=E5ldal wrote:
>=20
> In article <5a1fc2$42t@panix.com>, comeau@panix.com (Greg Comeau) wrote=
:
> >I think it's less an issue of it being sensible than this:
> >What real problems does it solve?
>=20
> You can no longer mix up the null-pointer with the integer zero.
(not just 0, but any constant which evaluates to 0, remember that! :-)
How much will this really fix? Can it be done without changes to the
language?
> Assume two functions with this prototypes:
> void f1(char*, long);
> void f2(int, long);
Meaningless. Give them real names and then tell me how obvious the
errors below become.
> {
> long l;
> char* c;
>=20
> // assign something l and c
>=20
> // let's call the function, I want zero for the int argument
> f1(0, l); // oops wrong function
And you're saying this is the compiler's fault?!? It's yours for naming
the functions with names so "close".
> // let's call the other function, I want NULL for the char* arg=
ument
> f2(NULL, l*2); // oops wrong function
Ditto.
> }
>=20
> With the proposal, this defective code won't compile.
With member templates, I believe you can make a nice NULL type that
would cause the above not to compile. And member templates *are* in the
standard.
> But this is a silly example,
You got that right. So why did you post it?
> in C++ we use overloading and thing will
> work much better, wouldn't they?
Assuming the overloaded functions do the same thing. If they don't, then
their names should not be the same (or even close, like the above f1 and
f2).
> Let's try:
>=20
> void f(char*, long);
> void f(int, long);
Well, what do they do? Do they convert the char string to a number (or
vice versa)? Maybe using a real string here would help?
> {
> long l;
> char* c;
>=20
> f(0, l);
> f(NULL, l);
> }
>=20
> Works great, huh?
I guess I don't understand why one takes a pointer, and another a value.
Maybe if they took a pointer to char and pointer to int, you would get
better results.
> It's really bad that C++ should be even worse than C in this case :-(
Excuse me, are you saying that your C++ compiler didn't accept the C
version above? Or are you saying that C++ is worse because it offers
more options?
--=20
Chelly Green | chelly@eden.com | C++ - http://www.eden.com/~chelly
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1996/12/23 Raw View
If a null-pointer keyword aren't to be added, I propose that something
else is changed to allow the NULL macro to be defined like this:
#define NULL ((void*)0)
This is how it use to be defined in C and it will save us from some
trouble, e.g.
int i = NULL;
won't be allowed.
(void*)0 won't work now since implicit cast from void* to
somethingelse* isn't allowed, maybe that rule can be relaxed to not
apply to null-pointer constants.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1996/12/26 Raw View
d96-mst@nada.kth.se (Mikael St ldal) writes:
|> If a null-pointer keyword aren't to be added, I propose that something
|> else is changed to allow the NULL macro to be defined like this:
|>
|> #define NULL ((void*)0)
|>
|> This is how it use to be defined in C and it will save us from some
|> trouble, e.g.
|>
|> int i = NULL;
|>
|> won't be allowed.
|>
|> (void*)0 won't work now since implicit cast from void* to
|> somethingelse* isn't allowed, maybe that rule can be relaxed to not
|> apply to null-pointer constants.
This was proposed, in almost exactly the form you suggest. (I know. I
wrote the proposal.) It was rejected by the committee.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)3 88 14 49 00
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Michael R Cook <mcook@cognex.com>
Date: 1996/12/27 Raw View
>>>>> "JK" == James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
JK> d96-mst@nada.kth.se (Mikael St ldal) writes:
JK> |> If a null-pointer keyword aren't to be added, I propose [...]
JK> This was proposed, in almost exactly the form you suggest. (I know. I
JK> wrote the proposal.) It was rejected by the committee.
Isn't this merely a QOI issue? It wouldn't take very sophisticated compiler
technology to give a warning for constructs like `int i = NULL'. To start,
the vendor could simply do `#define NULL __null', no?
--
Michael Cook <mcook@cognex.com> <http://ftp.cognex.com/~mcook/>
Telephone: +1 508 650 3251 Fax: +1 508 650 3336
Cognex Corporation, One Vision Drive, Natick, Massachusetts 01760-2059
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: wkdugan@ix.netcom.com (Bill Dugan)
Date: 1996/12/27 Raw View
James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
snip
>This was proposed, in almost exactly the form you suggest. (I know. I
>wrote the proposal.) It was rejected by the committee.
What was their reason? It sounds like a sensible idea.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1996/12/27 Raw View
In article <59vgan$9bl@sjx-ixn10.ix.netcom.com> wkdugan@ix.netcom.com (Bill Dugan) writes:
>James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
>
>snip
>
>>This was proposed, in almost exactly the form you suggest. (I know. I
>>wrote the proposal.) It was rejected by the committee.
>
>What was their reason? It sounds like a sensible idea.
I think it's less an issue of it being sensible than this:
What real problems does it solve?
What real problems does it leave unsolved?
How does it solve current problems better than the current situation
and/or other current solutions?
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
***WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1996/12/27 Raw View
In article <lVmuyEpfh6WV090yn@nada.kth.se> d96-mst@nada.kth.se (Mikael St ldal) writes:
>If a null-pointer keyword aren't to be added, I propose that something
>else is changed to allow the NULL macro to be defined like this:
>
>#define NULL ((void*)0)
>
>This is how it use to be defined in C
Maybe your compiler used to define it like this, but C certainly
never mandated it to do so.
> and it will save us from some
>trouble, e.g.
>
>int i = NULL;
>
>won't be allowed.
This begs for why using NULL gains little (at least IMO, I don't mention
this to open up a debate on it).
>(void*)0 won't work now since implicit cast from void* to
>somethingelse* isn't allowed, maybe that rule can be relaxed to not
>apply to null-pointer constants.
In te long run, there is no perfect solution, but, if you'll excuse my
slang, maybe using the "keyword" 0 would help instead of using NULL?
If not, the problem you are trying to solve is not clear to me.
I believe that your initial statement is that NULL should be absolutely
defined as (void*)0, but for whatever you think that gains you, it
still doesn't gain you enough.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
***WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1996/12/28 Raw View
In article <59vekt$7pg@erawan.cognex.com> Michael R Cook <mcook@cognex.com> writes:
>>>>>> "JK" == James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
>
> JK> d96-mst@nada.kth.se (Mikael St ldal) writes:
> JK> |> If a null-pointer keyword aren't to be added, I propose [...]
>
> JK> This was proposed, in almost exactly the form you suggest. (I know. I
> JK> wrote the proposal.) It was rejected by the committee.
>
>Isn't this merely a QOI issue? It wouldn't take very sophisticated compiler
>technology to give a warning for constructs like `int i = NULL'. To start,
>the vendor could simply do `#define NULL __null', no?
Perhaps not in a strict mode (I'd have to check the wording), but yes.
OTOH, at least I was not clear what the poster really wanted to address,
so am not sure how this fits into addressing his concerns.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C++ 4.0 front-end pre-release
***WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/12/30 Raw View
comeau@panix.com (Greg Comeau) writes:
> In article <59vgan$9bl@sjx-ixn10.ix.netcom.com> wkdugan@ix.netcom.com (Bill Dugan) writes:
> >James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
> >
> >snip
> >
> >>This was proposed, in almost exactly the form you suggest. (I know. I
> >>wrote the proposal.) It was rejected by the committee.
> >
> >What was their reason? It sounds like a sensible idea.
>
> I think it's less an issue of it being sensible than this:
> What real problems does it solve?
> What real problems does it leave unsolved?
> How does it solve current problems better than the current situation
> and/or other current solutions?
I think that this was part of it. I was unable to attend the meeting
where it was discussed, so I can only say from hearsay, but apparantly,
part of the opposition was that it didn't buy us enough; some of the
opponents wanted a real nil type.
IMHO, the major problem was simple: if I'm dealing with pointers, I want
the fact apparent, and want to use NULL, rather than 0. However, I most
definitly don't want "f( NULL )" to call "f( int )".
An additional problem is that of matching types when using stdarg. My
proposal didn't do anything to address this; NULL had type void*, and if
the called function expected a char*, the results were undefined. This
could be solved by creating a new, special type for NULL; passing this
type (uncast) as a variadic arg would then be an error.
I didn't opt for this second solution because I didn't feel variadic
args are that important (in C++), introducing a new type has a major
effect on the standard (think of template matching), my proposal was
made very late in the game, and I wanted to keep the impact on the
standard as limited as possible. Globally, I think that the new type
would be an even better solution, but it would have required
significantly more work, and IMHO, also risked delaying the standard.
If you do like the proposal, Fergus Henderson implemented it, or
something very close to it, in g++. I think that current releases of
g++ use either Fergus' implementation, or something similar, and that
unless you specify -pendantic, "((void*)0)" works as a null pointer.
(Since g++ normally picks up part of its headers from the local
environment, I don't think that they can redefine NULL.)
--
James Kanze +33 (0)3 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]