Topic: Dynamic_cast of 0


Author: James.Kanze@dresdner-bank.com
Date: 1999/01/14
Raw View
In article <369AD865.6CFD@nospam.aracnet.com>,
  sj_nospam@nospam.aracnet.com wrote:

    [...]
> It would, I suspect, have its own type, say null_t.
>
> Type null_t would have the following properties:

I like the proposal, but it still isn't complete:

    [...]
> *  One cannot declare any variables of type null_t; make any parameters
>    of any function of type null_t, cast to null_t, etc.  Indeed,
>    the symbol "null_t" is neither a keyword nor a library symbol; it
>    is only used here as a placeholder for "the type of null".

    template< class T > T f( T v ) { return v ; }

    void* p = f( NULL ) ;           //  I hope this is legal
    cout << sizeof( f( NULL ) ) ;   //  What should be output?
                                    //  (Would 0 be legal?)

Your solution resembles the state of null in Java, but Java doesn't have
templates.

--
James Kanze                                           GABI Software, S   rl
Conseils en informatique orient    objet  --
                          --  Beratung in industrieller Datenverarbeitung
mailto: kanze@gabi-soft.fr          mailto: James.Kanze@dresdner-bank.com

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


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






Author: David R Tribble <dtribble@technologist.com>
Date: 1999/01/14
Raw View
David R Tribble wrote:
> The 'null' keyword would
> be valid as a pointer operand (convertible to any pointer type) in
> expressions like these:
> ...
>     printf("%p", null);    // Passed as void *

Mike Schilling wrote:
> No, no, no, no, no, no, no.
>
> The main point of a null keyword, to me, is to avoid silently breaking
> type correctness.  This should be a compilation error: "null" used in
> a context where its type cannot be determined.  If you mean
> (void *)null, and not (int *)null or ((void *)())null, say so.

Yes, that's an old but valid argument.

On the other hand, the only printf format specifiers that expect a
pointer are %s and %p, both of which can safely receive null as a
char* or void*.

But on the other hand, what about user functions with pointer
varargs?  In this case, yes, an explicit cast of 'null' would
be appropriate.

I'm currently undecided.  It would be nice to be able to pass
'null' as an argument without needing an explicit cast (since we
wouldn't need explicit casts anywhere else we use 'null'), but
I agree that type safety is important (especially for catching
erroneous calls).  Of course, I'd just be happy with a 'null' in
the first place.

[See my next post.]

-- David R. Tribble, dtribble@technologist.com --


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






Author: David R Tribble <dtribble@technologist.com>
Date: 1999/01/14
Raw View
Brad Daniels wrote:
> I believe it was in this newgroup that somebody posted a nifty
> definition for "nil" some time ago:
>
>    const struct nil_t {
>        nil_t() {}
>        template <class X> operator X *() const { return 0; }
>    } nil;
>
> I may have messed up on constness, but the above seems to have all the
> properties one would desire of null.

Except that this is legal:

    nil_t    my_own_object;    // a new synonym for null

This is probably benign, except that a program could then contain
several null pointers, all with different names.  Better to make
it an anonymous type, as in...

Petter Urkedal wrote:
> I believe the `type' in question is not a type, but a class template,
>
>     struct
>     {
>         template<class T> operator T*() { return 0; }
>     } null;
>
> I.e. I believe this `null' object has the desired properties.
...
> Especially,
>
>   * `null' does not convert to an integer type, which is good when
>     calling overloaded functions.
>
>   * neither does it prefer conversion to `void*' compared to any
>     other pointer (as I understand, this is the problem with
>     `#define null ((void*)0)')

Of course, we'll have to wait a year or two before enough C++
compilers become compliant to start using this extensively.

This is a good start, but it still has some shortcomings:

    * sizeof(null)?

    * conversion/comparison to member pointer types?

    * disallow '&null'.

I believe someone posted a more complete solution on comp.std.c++
a few months ago.  But again, it used advanced features, so we'll
have to wait a while to use it widely.

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





Author: Darron Shaffer <darron.shaffer@beasys.com>
Date: 1999/01/14
Raw View
James.Kanze@dresdner-bank.com writes:

> In article <369AD865.6CFD@nospam.aracnet.com>,
>   sj_nospam@nospam.aracnet.com wrote:
>
>     [...]
> > It would, I suspect, have its own type, say null_t.
> >
> > Type null_t would have the following properties:
>
> I like the proposal, but it still isn't complete:
>
>     [...]
> > *  One cannot declare any variables of type null_t; make any parameters
> >    of any function of type null_t, cast to null_t, etc.  Indeed,
> >    the symbol "null_t" is neither a keyword nor a library symbol; it
> >    is only used here as a placeholder for "the type of null".
>
>     template< class T > T f( T v ) { return v ; }
>
>     void* p = f( NULL ) ;           //  I hope this is legal
>     cout << sizeof( f( NULL ) ) ;   //  What should be output?
>                                     //  (Would 0 be legal?)
>
> Your solution resembles the state of null in Java, but Java doesn't have
> templates.
>

A possible solution is to declare the underlying type of null (null_t
or whatever) as having internal linkage.  Therefore, it can't be used
as a template parameter.

I think your code above should be illegal -- if you can't declare a
function returning null_t directly why should a template allow you to
do this?

I think David Tribble already said that you can't sizeof(null).

I think that:

    void f(int x, ...);

    x(1, null);

should be illegal.  I also think that this is the only important
characteristic of null that can't be faked with a template class,
without requiring changes to the language.

If I only had a compiler that would do the necessary things.

Darron Shaffer

--
 __  __  _
 _ ) ___ _\   Enterprise Middleware Solutions Darron J Shaffer
 __) __    \  BEA Systems Inc.   Sr. Software Engineer
              17101 Preston Rd   darron.shaffer@beasys.com
              LB# 115, Ste 260    Voice: (972) 738-6137
              Dallas, TX 75248    Fax:   (972) 738-6111
       http://www.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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1999/01/13
Raw View
David R Tribble wrote:
> Sigh.  Can I ask, once again, for a 'null' keyword?
>
Ron Natalie <ron@sensor.com>
> You can ask, but then I'd have to ask what the type of
> "null" is?

David R Tribble wrote:
> Exactly what you would expect it to be.  The 'null' keyword would
> be valid as a pointer operand (convertible to any pointer type) in
> expressions like these:

Ron Natalie <ron@sensor.com> wrote:
> You still haven't told me what type it has.


I believe the `type' in question is not a type, but a class template,

    struct { template<class T> operator T*() { return 0; } } null;

I.e. I believe this `null' object has the desired properties.  You
may try it with the following program, which fails to compile if
`ERROR1', ..., `ERROR3' is defined.  Especially,

  * `null' does not convert to an integer type, which is good when
    calling overloaded functions.

  * neighter does it prefer conversion to `void*' compared to any other
    pointer (as i understand, this is the problem with
    `#define null ((void*)0)')


 -petter.

---------null.cc----------------------------------------------------------
#include <iostream>

using namespace std;

struct { template<class T> operator T*() { return 0; } } null;

void f(char) {}
void f(char*) {}

void g(char*) {}
void g(void*) {}

void h(int) {}

main() {
    int **p1 = null;     // OK
    double *p2 = null;   // OK
    char *p3;
    p3 = null;           // OK

    int (*fp)(short);
    fp = null;           // OK

    f(null);   // OK

#ifdef ERROR1
    int i;
    i = null;  // invalid conversion
#endif
#ifdef ERROR2
    g(null);   // ambiguous
#endif
#ifdef ERROR3
    h(null);   // invalid conversion
#endif
}
-----------------------------------------------------------------------

Compilation with egcs gives:

------> c++ -DERROR1  -c null.cc
null.cc: In function `int main()':
null.cc:30: `struct {anonymous}' used where a `int' was expected

------> c++ -DERROR2  -c null.cc
null.cc: In function `int main()':
null.cc:33: call of overloaded `g ({anonymous struct} &)' is ambiguous
null.cc:12: candidates are: g(char *)
null.cc:13:                 g(void *)

------> c++ -DERROR3  -c null.cc
null.cc: In function `int main()':
null.cc:36: `struct {anonymous}' used where a `int' was expected


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





Author: David R Tribble <dtribble@technologist.com>
Date: 1999/01/11
Raw View
David R Tribble wrote:
> Sigh.  Can I ask, once again, for a 'null' keyword?

Ron Natalie <ron@sensor.com>
> You can ask, but then I'd have to ask what the type of
> "null" is?

Exactly what you would expect it to be.  The 'null' keyword would
be valid as a pointer operand (convertible to any pointer type) in
expressions like these:

    class Base { ... };
    class Der: Base { ... };

    void *  vp = null;
    int *   ip = null;             // No cast required
    Base *  bp = null;
    Der *   dp1 = bp;
    Der *   dp2 = null;
    int     (*fp)(int v) = null;   // No cast required

    extern void  foo(const char *msg, Base *bp);
    foo(null, null);

    dp1 = static_cast<Der *>(null);

    extern void  quux(char *p);
    extern void  quux(int i);
    quux(0);               // Error, ambiguous
    quux(null);            // Calls quux(char *)

    printf("%p", null);    // Passed as void *

Using 'null' in other contexts would be illegal, such as in these
expressions:

    int   i = null;        // Error
    char  c = null;        // Error

    i = c + null;          // Error;
    memset(bp, null, sizeof(*bp));    // Error

    extern void  bar(long v);
    bar(null);             // Error, bar(T *) does not exist

    extern void  baz(char *p);
    extern void  baz(Base *p);
    baz(null);             // Error, ambiguous

In other words, a 'null' keyword would behave in all of the good
ways that '0' does when it's used as a null pointer constant, but
in none of the bad ways.

-- David R. Tribble, dtribble@technologist.com --


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






Author: Ron Natalie <ron@sensor.com>
Date: 1999/01/11
Raw View
David R Tribble wrote:
>
> David R Tribble wrote:
> > Sigh.  Can I ask, once again, for a 'null' keyword?
>
> Ron Natalie <ron@sensor.com>
> > You can ask, but then I'd have to ask what the type of
> > "null" is?
>
> Exactly what you would expect it to be.  The 'null' keyword would
> be valid as a pointer operand (convertible to any pointer type) in
> expressions like these:

You still haven't told me what type it has.

>
>     printf("%p", null);    // Passed as void *

How does it know to do this?



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






Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1999/01/12
Raw View
On 11 Jan 1999 21:33:43 GMT, David R Tribble <dtribble@technologist.com> wrote:

>In other words, a 'null' keyword would behave in all of the good
>ways that '0' does when it's used as a null pointer constant, but
>in none of the bad ways.

Yes, this 'null' is better than the function 'null<T>()'
I proposed in my earlier post, and also better than the
'struct null<T>' method Christopher proposed in his
earlier post.  However, it does require a change to the
language.  It seems like a harmless change, and it would
be very useful.  So what's stopping the standard
committee from adopting this change?  Anyway, would you
say that old style pointer expressions that use '0'
should be deprecated.  Eg, is this ok: "int * p=0"?
Since we have 'null', this should be deprecated, and
later on, it should be disallowed; we should always use
"int * p=null".

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





Author: Scott Johnson <sj_nospam@nospam.aracnet.com>
Date: 1999/01/12
Raw View
Ron Natalie wrote:
>
> David R Tribble wrote:
> >
> > David R Tribble wrote:
> > > Sigh.  Can I ask, once again, for a 'null' keyword?
> >
> > Ron Natalie <ron@sensor.com>
> > > You can ask, but then I'd have to ask what the type of
> > > "null" is?
> >
> > Exactly what you would expect it to be.  The 'null' keyword would
> > be valid as a pointer operand (convertible to any pointer type) in
> > expressions like these:
>
> You still haven't told me what type it has.

It would, I suspect, have its own type, say null_t.

Type null_t would have the following properties:

*  Exactly one legal value--null.

*  Can be implicitly cast to any pointer- or pointer-to-function type,
regardless of constness or volatileness.  Can also be explicitly cast by
static_cast or reinterpret_cast to any pointer type.  Whether or not
null can be an argument to dynamic_cast seems to be a topic of debate in
this thread. :)

ie

const Foo *pFoo = null;
void (*pBar)(void) = null;

The result of such a conversion is the appropriate null pointer of the
specified type.

*  Does NOT cast implicitly to int, bool, or any other
non-pointer         scalar type.  Explicit static_casts to these
integral types produce     0.

*  Deferencing, subscripting, taking the address of, assigning to,
   or using as the left hand side of ->, are all undefined for null.
   (One can get around this by static_cast'ing to their
   favorite pointer type, and THEN doing the arithmetic.)

*  Using null as an argument to any arithmetic (+, -, *, /, %,
   unary -), logical (&&, ||, !) or bitwise (|, &, ^, ~) expression
   is undefined.

*  One cannot declare any variables of type null_t; make any parameters
   of any function of type null_t, cast to null_t, etc.  Indeed,
   the symbol "null_t" is neither a keyword nor a library symbol; it
   is only used here as a placeholder for "the type of null".

*  null may be compared for equality (==) or inequality (!=) with
   any other pointer; the test for equality returns true if the other
   pointer is the null pointer of that type, false otherwise.  The
   test for inequality is reversed.

*  null == null returns true; null != null returns false.



> >     printf("%p", null);    // Passed as void *
>
> How does it know to do this?

By being a new type with the above properties.


Scott


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






Author: "Brad Daniels" <brad.daniels@missioncritical.com>
Date: 1999/01/12
Raw View

David R Tribble wrote in message <369A4D22.AB72B34C@technologist.com>...
>
>David R Tribble wrote:
>> Sigh.  Can I ask, once again, for a 'null' keyword?
>
>Ron Natalie <ron@sensor.com>
>> You can ask, but then I'd have to ask what the type of
>> "null" is?
>
>Exactly what you would expect it to be.  The 'null' keyword would
>be valid as a pointer operand (convertible to any pointer type) in
>expressions like these:
...

I believe it was in this newgroup that somebody posted a nifty definition
for "nil" some time ago:

const struct nil_t {
    nil_t() {}
    template <class X> operator X *() const { return 0; }
} nil;

I may have messed up on constness, but the above seems to have all the
properties one would desire of null.

- Brad




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






Author: David R Tribble <dtribble@technologist.com>
Date: 1999/01/13
Raw View
David R Tribble wrote:
> Sigh.  Can I ask, once again, for a 'null' keyword?

Ron Natalie <ron@sensor.com>
> You can ask, but then I'd have to ask what the type of
> "null" is?

David R Tribble wrote:
> Exactly what you would expect it to be.  The 'null' keyword would
> be valid as a pointer operand (convertible to any pointer type) in
> expressions like these:
> ...

Ron Natalie wrote:
> You still haven't told me what type it has.

Scott Johnson wrote:
> It would, I suspect, have its own type, say null_t.

Exactly.  The 'null' keyword has the type 'null pointer constant',
or, to put it simply, it has type 'null'.  (Inventing an explicit
type 'null_t' would be fine for expository reasons, but might not be
necessary; see below.)

> Type null_t would have the following properties:
>
> *  Exactly one legal value -- null.

In other words, you cannot declare an object or function to be of
type 'null_t'.  Only one such "object" exists, and that is the
keyword 'null'.

> *  Can be implicitly cast to any pointer- or pointer-to-function type,
> regardless of constness or volatileness.  Can also be explicitly cast
> by static_cast or reinterpret_cast to any pointer type.  Whether or
> not null can be an argument to dynamic_cast seems to be a topic of
> debate in this thread. :)
>
> ie
>    const Foo *pFoo = null;
>    void (*pBar)(void) = null;
>
> The result of such a conversion is the appropriate null pointer of the
> specified type.

It would also be legal to assign or cast 'null' to any pointer to
member type.  It could also be cast to any cv-pointer type having any
combination of 'const' and 'volatile' modifiers.

> *  Does NOT cast implicitly to int, bool, or any other
> non-pointer scalar type.  Explicit static_casts to these
> integral types produce 0.

I would go further and state that 'null' cannot be cast directly
to any type other than pointer types.  To cast a null pointer
into an integer, you must first explicitly cast the 'null' into
a specific pointer type, and then cast that pointer value into the
target integer type:

    long p = static_cast<long>(null);  // Error, illegal
    long q = static_cast<long>(static_cast<void*>(null)); // Okay
    long r = static_cast<long>((void*)null);              // Okay
    long r = static_cast<long>((const char *)null);       // Okay

This allows for the proper semantics on systems having different
bit representations for different pointer types (where, for example,
a null char pointer might have a different bit pattern than a null
int pointer or null function pointer).

> *  Deferencing, subscripting, taking the address of, assigning to,
>    or using as the left hand side of ->, are all undefined for null.
>    (One can get around this by static_cast'ing to their
>    favorite pointer type, and THEN doing the arithmetic.)

This would be not just undefined, but illegal.

> *  Using null as an argument to any arithmetic (+, -, *, /, %,
>    unary -), logical (&&, ||, !) or bitwise (|, &, ^, ~) expression
>    is undefined.

Not just undefined, but illegal.  Also, 'null' is not an l-value.

> *  One cannot declare any variables of type null_t; make any
>    parameters
>    of any function of type null_t, cast to null_t, etc.  Indeed,
>    the symbol "null_t" is neither a keyword nor a library symbol; it
>    is only used here as a placeholder for "the type of null".

As I wrote above, the 'null_t' type is only for expository purposes,
used in order to explain the semantics of the 'null' keyword.  We
might not even need 'null_t' in order to do this; it's possible to
write all the semantic rules for 'null' using the phrases "null
keyword" and "null pointer constant" in place of "null_t" and "null
pointer type".

> *  null may be compared for equality (==) or inequality (!=) with
>    any other pointer; the test for equality returns true if the other
>    pointer is the null pointer of that type, false otherwise.  The
>    test for inequality is reversed.

> *  null == null returns true; null != null returns false.

> > >     printf("%p", null);    // Passed as void *
> >
> > How does it know to do this?
>
> By being a new type with the above properties.

Or by adding the following rule:

  *  When 'null' is passed as a varargs argument, it is equivalent
     to passing a null pointer of type 'pointer to void' (i.e., the
     value '(void*)null'.)

     This makes it legal to pass 'null' unadorned when a void* or
     char* argument is expected.  It also means that an explicit
     cast is required when passing 'null' as a vararg of any other
     pointer type.

So now does all this answer the question "What type is 'null'?"
to everyone's satisfaction?

Siemel B. Naran (sbnaran@uiuc.edu) wrote:
> ...  Anyway, would you
> say that old style pointer expressions that use '0'
> should be deprecated.  Eg, is this ok: "int * p=0"?
> Since we have 'null', this should be deprecated, and
> later on, it should be disallowed; we should always use
> "int * p=null".

All of my suggestions and proposals for 'null' state quite clearly
that we would not illegalize the use of '0' for a null pointer
constant.  Phase I is simply adding 'null' to C++; phase II is
deprecating '0' as the null pointer constant.  Personally, I doubt
that we'll ever get all programs to move to phase II.  But we could
probably get all new code to move to it, and (more importantly) we
could get future C++ textbooks to adopt 'null'.

See <http://www.flash.net/~dtribble/text/c9xnull.txt> for the full
text of my original proposal.  It covered all of the issues
mentioned by Scott (the only difference being that I now feel that
'null' cannot be cast directly to an integer type).  It was written
in late 1997, and even though it generated a lot of newsgroup
discussion at the time, it attracted very little real support in
the end.

I and a few others occasionally mention 'null' on the C and C++
newsgroups just to keep the fires burning.  Maybe, someday, just
maybe, we might get 'null'.  But I'm not holding my breath.

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





Author: David R Tribble <dtribble@technologist.com>
Date: 1998/12/18
Raw View
Steve Clamage <stephen.clamage@sun.com> wrote:
> Personally, I have always loathed the overloading of 0 to
> mean null pointer, and in the abstract, I would prefer a
> keyword such as 'nil'.

Christopher Eltschka wrote:
> I prefer the null object solution (on up to date compilers):
>     struct
>     {
>         template<class T> operator T*() const
>         {
>             return (T*)0;
>         }
>     } null;
>
> Now you can do
>     char* p=null; // null.operator char*() -> (char*)null
>     void f(int*);
>     void f(int);
>     f(null); // calls f(int*)
>     void g(char*);
>     void g(int*);
>     g(null); // ambiguous

Your solution is almost correct.  But what about:

    void *  p = &null;   // Should be illegal, but isn't

Someone else suggested a more comprehensive solution a few months
ago on this newsgroup along similar lines.  I don't know how
complex it was, but I do remember it had a problem with this,
which your solution also suffers from:

    extern void  foo(int a, ...);

    foo(0, null);
    printf("%p", null);

But don't give up trying.  I would very much like a workable
'null' as close to a built-in keyword as possible.

-- David R. Tribble, dtribble@technologist.com --


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






Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/12/18
Raw View
On 14 Dec 1998 17:25:57 GMT, Christopher Eltschka

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


>I prefer the null object solution (on up to date compilers):
>
>struct
>{
>  template<class T> operator T*() const
>  {
>    return (T*)0;
>  }
>} null;

To avoid multiple definition link errors at link time, the 'null'
object should be const (so that it has internal linkage).

The reason why I prefer the nil<T>() or nil(T) method is that the
return argument of the function is deduced entirely from the
function arguments.  Both these nil functions are functions taking
one argument (we are considering template arguments and function
arguments on the same grounds here).  This single argument says
what the return type should be.

By contrast, the conversion operator method seems a little like
overloading by return value, so I don't like it that much.  In
fact, the current '0' is like overloading by return value --
that is, '0' could be an int* or std::pair<int,int>*, depending
on how it is used.  If there isn't sufficient context to say
which pointer we want, '0' is interpreted as an int.

But as creating null pointers is so common, the null<int>()
method looks cumbersome and ugly.  So '0' and null are good
alternatives.

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






Author: AllanW@my-dejanews.com
Date: 1998/12/15
Raw View
In article <36752950.EE73D5BC@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> The advantage is that you don't need an object of that type (which
> may not be easy to get - think of abstract types where it makes sense
> to have (Abstract*)0, but it doesn't make sense to have an object
> of that type. Or think of a class where the only constructor is
> very expensive or even invokes observable behaviour. Would you use
> your method on the class AtomicBombTrigger, where the constructor lets
> the bomb explode? ;-))

Any project with a non-whimsical need for an AtomicBombTrigger class
will have many safeguards in place, not the least of which is code
reviews. Presumably an implementation of AtomicBombTrigger which
detonates the bomb in the ctor wouldn't even get far enough to be
presented at the code review, because the author would fear the
resulting ridicule. (Hey Christopher -- hope that code doesn't blow
up!) (Hey Christopher -- that sure was a loud sneeze!) (Hey
Christopher -- loosen up! Try not to have such a short fuse!)
(Hey Christpoher -- just saw your latest work. Smokin'!) (Hey
Christopher -- got the time? Bomb? Hehehe) (etc.) :-)

Personally, I'm above that sort of thing, but there are always
others...

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


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






Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/12/11
Raw View
David R Tribble <dtribble@technologist.com> writes:
> Sigh.  Can I ask, once again, for a 'null' keyword?

Steve Clamage wrote:
> We did discuss this in the C++ committee.
>
> The problem is (as always) C compatibility, not to mention
> compatibility with years of C++ programming.

A C++ compiler that claims compatibility could simply supply a
true null pointer value when passing extern "C" function arguments
of pointer type.  C++ compilers have the advantage of knowing
exactly what the argument types are for every function whether
they are C++ or not.  (Also see my next response below.)

> The language
> still must accept zero-valued constant integral expressions
> as null pointer constants. (You don't want every C++ program
> to break on every use of pointers, with no quick fix.)

My suggestion was to introduce the 'null' keyword and simply deem
the use of '0' as deprecated practice; I don't think it's a good
idea to abolish it outright so soon.  In ten years, yes, but not
today.  Unfortunately, it's now going to be more like 15 or 20
years away, or maybe even never.

> Adding (an additional) keyword that would in fact just be
> an alternative syntax didn't generate much enthusiasm.
> (To retain compatibility, you can't just make NULL the
> keyword.)

No, but you can do this:
    #ifdef __cplusplus
      #define NULL   null
    #else // C
      #define NULL   ((void*)0)
    #endif

(If people didn't like alternative syntaxes, why do we have both
'#if defined sym' and '#if defined(sym)', or 'sizeof x' and
'sizeof(x)', or countless others?)

But 'null' is more than simply just an alternative syntax for '0'.
It's more type-safe and less ambiguous.  Not to mention clearer
to read.  It's a true null pointer constant, everywhere, unlike
integer zero.

Sorry, but the reasons the committee gave are not convincing enough
to preclude the addition of a 'null' (or 'nil') keyword to C++.

> Personally, I have always loathed the overloading of 0 to
> mean null pointer, and in the abstract, I would prefer a
> keyword such as 'nil'.

You say 'nil', I say 'null', same thing.

> The solution is to hop into your time machine and ask Dennis
> Ritchie to include a keyword for null pointer in his design
> of C. :-)

Or start over with a new, cleaner language having a 'null' keyword.
Oh, wait, that's Java.  Or borrow from an older language that's
had it for years, such as Eiffel, Ada, Pascal, or PL/1.  Hell,
even COBOL has had a NULL since 1985.  ;-(

-- David R. Tribble, dtribble@technologist.com --


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






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/14
Raw View
Nathan Myers wrote:

> Siemel Naran<sbnaran@uiuc.edu> wrote:
> > Steve Clamage <stephen.clamage@sun.com> wrote:
> >
> >>Personally, I have always loathed the overloading of 0 to
> >>mean null pointer, and in the abstract, I would prefer a
> >>keyword such as 'nil'.
> >
> >How about this?
> >
> > template <class T> inline T * nil() { return (T*)0; }
>
> We've been through this enough times for it to be an FAQ.
> Use:
>
>   template <class T> inline T* nil(T&) { return (T*)0; }
>
> You pass a convenient object of the right type, and nil returns
> a null pointer of the same type.
>
>   Foo f;
>   return nil(f);  // same as return (Foo*)0;

I prefer the null object solution (on up to date compilers):

struct
{
  template<class T> operator T*() const
  {
    return (T*)0;
  }
} null;

Now you can do

char* p=null; // null.operator char*() -> (char*)null

void f(int*);
void f(int);

f(null); // calls f(int*)

void g(char*);
void g(int*);

g(null); // ambiguous

The advantage is that you don't need an object of that type (which
may not be easy to get - think of abstract types where it makes sense
to have (Abstract*)0, but it doesn't make sense to have an object
of that type. Or think of a class where the only constructor is
very expensive or even invokes observable behaviour. Would you use
your method on the class AtomicBombTrigger, where the constructor lets
the bomb explode? ;-))


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






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/10
Raw View
David R Tribble <dtribble@technologist.com> writes:

>Sigh.  Can I ask, once again, for a 'null' keyword?

We did discuss this in the C++ committee.

The problem is (as always) C compatibility, not to mention
compatibility with years of C++ programming. The language
still must accept zero-valued constant integral expressions
as null pointer constants. (You don't want every C++ program
to break on every use of pointers, with no quick fix.)

Adding (an additional) keyword that would in fact just be
an alternative syntax didn't generate much enthusiasm.
(To retain compatibility, you can't just make NULL the
keyword.)

Personally, I have always loathed the overloading of 0 to
mean null pointer, and in the abstract, I would prefer a
keyword such as 'nil'.

The solution is to hop into your time machine and ask Dennis
Ritchie to include a keyword for null pointer in his design
of C. :-)

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


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






Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/12/10
Raw View
On 10 Dec 1998 19:09:08 GMT, Steve Clamage <stephen.clamage@sun.com> wrote:

>Personally, I have always loathed the overloading of 0 to
>mean null pointer, and in the abstract, I would prefer a
>keyword such as 'nil'.

How about this?

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

To me '0' sounds like overloading by return value.  That is, whether
'0' is an int, a double*, a std::pair<int,int>*, or whatever, depends
on how it is used.  If the compiler can't determine how it is used,
it takes it to be an int.
   int k=0; // '0' is an int
   double * p=0; '0' is a double*

Similarly, we could have left out the <...> arguments for dynamic_cast
and the other casts.  For example,
   Base * b = new Derived();
   Derived * d = dynamic_cast(b);
The dynamic_cast obviously means dynamic_cast<Derived*>, so it is not
necessary to provide the template argument.  However, this amounts to
overloading by return value -- or template argument deduction by
return value -- and this is not good for program maintainance.

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






Author: Pete Becker <petebecker@acm.org>
Date: 1998/12/10
Raw View
Siemel Naran wrote:
>
>
> How about this?
>
>  template <class T> inline T * nil() { return (T*)0; }

Used like this:

f(nil<foo>());

Pretty ugly...

>
> To me '0' sounds like overloading by return value.  That is, whether
> '0' is an int, a double*, a std::pair<int,int>*, or whatever, depends
> on how it is used.  If the compiler can't determine how it is used,
> it takes it to be an int.
>    int k=0; // '0' is an int
>    double * p=0; '0' is a double*
>
> Similarly, we could have left out the <...> arguments for dynamic_cast
> and the other casts.  For example,
>    Base * b = new Derived();
>    Derived * d = dynamic_cast(b);
> The dynamic_cast obviously means dynamic_cast<Derived*>, so it is not
> necessary to provide the template argument.

Intermediate *ip = dynamic_cast<Derived *>(b);

Yes, the type is necessary. This gives a null pointer if the object
pointed to is not of type Derived, even though the result is being
assigned to a pointer to Intermediate.

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


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






Author: Ron Natalie <ron@sensor.com>
Date: 1998/12/10
Raw View
David R Tribble wrote:
>
> Sigh.  Can I ask, once again, for a 'null' keyword?
>

You can ask, but then I'd have to ask what the type of
"null" is?



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






Author: AllanW@my-dejanews.com
Date: 1998/12/10
Raw View
In article <74mjpp$b15$1@uuneo.neosoft.com>,
  "Robert Stafford" <stafford@bindview.com> wrote:


> Christopher Eltschka wrote in message
> <366E89A4.5DFB1C35@physik.tu-muenchen.de>...
> >So would you say the compiler should accept the following code?
> >
> >#include <iostream>
> >
> >int f(long) { return 0; }
> >int f(short) { return 0; }
> >
> >int main()
> >{
> >  std::cout << f(1) << std::endl;
> >}
> >

> Certainly not.  (I am even pretty much convinced that it is a "good thing"
> that dynamic_cast<C*>(0) will not compile.)  The original questioner
> conceived of 0, in this context, as a generic nil pointer that could be
> converted to a nil pointer to any type and some operations on such a generic
> nil pointer can be consistently defined.  The problems with introducing a
> generic nil pointer have been discussed here at length, but in this
> particular case treating 0 as a generic nil pointer can be done reasonably
> and can cause no harm.

void * const nil = 0; // Generic nil pointer

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own



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






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/12/11
Raw View
Siemel Naran<sbnaran@uiuc.edu> wrote:
> Steve Clamage <stephen.clamage@sun.com> wrote:
>
>>Personally, I have always loathed the overloading of 0 to
>>mean null pointer, and in the abstract, I would prefer a
>>keyword such as 'nil'.
>
>How about this?
>
> template <class T> inline T * nil() { return (T*)0; }

We've been through this enough times for it to be an FAQ.
Use:

  template <class T> inline T* nil(T&) { return (T*)0; }

You pass a convenient object of the right type, and nil returns
a null pointer of the same type.

  Foo f;
  return nil(f);  // same as return (Foo*)0;

Nathan Myers
ncm@cantrip.org



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






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/11
Raw View
David R Tribble wrote:
>
> Reference: <366DBECD.F14D80D@wizard.net>
>
> James Kuyper wrote:
> > 0 is an integer, not a pointer. It's convertible to a null pointer of
> > any type, but it is not itself a pointer. It is a null pointer
> > constant, but by an oddity of the standard's terminology, it isn't a
> > null pointer.
>
> One of the horrible little things about C++.  Even C is better than
> C++ in this regard (but only a little better).

Not really; they both achieve the same result by different means:

C9X (I don't have a copy of the C89 standard) Section 6.3.2.3p3:
"An integer constant expression with the value 0, or such an expression
cast to type void *, is called a null pointer constant.46) If a null
pointer constant is assigned to or compared for equality to a pointer,
the constant is converted to a pointer of that type. Such a pointer,
called a null pointer, is guaranteed to compare unequal to a pointer to
any object or function."

C++ section 4.10:
"A null pointer constant is an integral constant expression (5.19)
rvalue of integer type that evaluates to zero. A null pointer constant
can be converted to a pointer type; the result is the null pointer value
of that type and is distinguishable from every other value of pointer to
object or pointer to function type."

Both definitions agree in making a null pointer constant an integer
type, not a pointer type. Both define a null pointer as the result of
the conversion of a null pointer constant to a pointer type; a null
pointer constant cannot be the result of such a conversion (since it
would not be an integer). Therefore a null pointer constant is not a
null pointer. This makes it a badly chosen name, by my standards.


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






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/11
Raw View
Ron Natalie <ron@sensor.com> writes:

>David R Tribble wrote:
>>
>> Sigh.  Can I ask, once again, for a 'null' keyword?
>>

>You can ask, but then I'd have to ask what the type of
>"null" is?

If it's a keyword, it doesn't need to have a unique type.
Consider, for example, "new". The type depends on context.
(For that matter, consider the name of an overloaded function.)

Some suggestions for template versions have been presented.
I don't find either of
 nil(char_ptr) // given "char* char_ptr;"
 nil<char*>
any more compelling than
 (char*)0
If a "nil" template becomes part of the standard library, that
would be different; it would become a standard idiom.

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


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






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/11
Raw View
AllanW@my-dejanews.com writes:

>void * const nil = 0; // Generic nil pointer

Not really.

 int foo(T* p); // T is some type
 ...
 char *p = nil; // error
 foo(nil);      // error

Since  something like this is the reason why you want a nil
pointer, that version of nil isn't very helpful.

In C, (void*)0 is a null pointer constant, because void* can
be implicitly converted to any object pointer type. Not so
in C++.

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


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






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/11
Raw View
James Kuyper wrote:
>
> David R Tribble wrote:
> >
> > Reference: <366DBECD.F14D80D@wizard.net>
> >
> > James Kuyper wrote:
> > > 0 is an integer, not a pointer. It's convertible to a null pointer of
> > > any type, but it is not itself a pointer. It is a null pointer
> > > constant, but by an oddity of the standard's terminology, it isn't a
> > > null pointer.
> >
> > One of the horrible little things about C++.  Even C is better than
> > C++ in this regard (but only a little better).
>
> Not really; they both achieve the same result by different means:
>
> C9X (I don't have a copy of the C89 standard) Section 6.3.2.3p3:
> "An integer constant expression with the value 0, or such an expression
> cast to type void *, is called a null pointer constant.46) If a null
> pointer constant is assigned to or compared for equality to a pointer,
> the constant is converted to a pointer of that type. Such a pointer,
> called a null pointer, is guaranteed to compare unequal to a pointer to
> any object or function."
>
> C++ section 4.10:
> "A null pointer constant is an integral constant expression (5.19)
> rvalue of integer type that evaluates to zero. A null pointer constant
> can be converted to a pointer type; the result is the null pointer value
> of that type and is distinguishable from every other value of pointer to
> object or pointer to function type."
>
> Both definitions agree in making a null pointer constant an integer
> type, not a pointer type. Both define a null pointer as the result of
> the conversion of a null pointer constant to a pointer type; a null
> pointer constant cannot be the result of such a conversion (since it
> would not be an integer). Therefore a null pointer constant is not a
> null pointer. This makes it a badly chosen name, by my standards.

Sorry, I didn't word that corrrectly to cover the fact that (void *)0 is
a C (but not a C++) null pointer constant:

"A null pointer constant need not be the result of such a conversion
(since it need not be an integer). Therefor a null pointer constant need
not be a null pointer."


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






Author: Jerry Leichter <leichter@smarts.com>
Date: 1998/12/11
Raw View
| >void * const nil = 0; // Generic nil pointer
|
| Not really.  [Examples elided.]
|
| In C, (void*)0 is a null pointer constant, because void* can
| be implicitly converted to any object pointer type. Not so
| in C++.

I've always liked the way Modula-3 did this:  There is a built-in type
NULL, which contains the single value NIL.  NIL is convertible to any
kind of pointer; the result is a pointer of that type that is guaranteed
not to refer to any object.

This suggests the following construct for a "null pointer" in C++:

 void()

(I.e., picture void as having a default constructor.)

       -- Jerry


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






Author: "Robert Stafford" <stafford@bindview.com>
Date: 1998/12/09
Raw View

Christopher Eltschka wrote in message
<366E89A4.5DFB1C35@physik.tu-muenchen.de>...
>So would you say the compiler should accept the following code?
>
>#include <iostream>
>
>int f(long) { return 0; }
>int f(short) { return 0; }
>
>int main()
>{
>  std::cout << f(1) << std::endl;
>}
>


Certainly not.  (I am even pretty much convinced that it is a "good thing"
that dynamic_cast<C*>(0) will not compile.)  The original questioner
conceived of 0, in this context, as a generic nil pointer that could be
converted to a nil pointer to any type and some operations on such a generic
nil pointer can be consistently defined.  The problems with introducing a
generic nil pointer have been discussed here at length, but in this
particular case treating 0 as a generic nil pointer can be done reasonably
and can cause no harm.




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






Author: David R Tribble <dtribble@technologist.com>
Date: 1998/12/10
Raw View
Reference: <366DBECD.F14D80D@wizard.net>

James Kuyper wrote:
> 0 is an integer, not a pointer. It's convertible to a null pointer of
> any type, but it is not itself a pointer. It is a null pointer
> constant, but by an oddity of the standard's terminology, it isn't a
> null pointer.

One of the horrible little things about C++.  Even C is better than
C++ in this regard (but only a little better).

Sigh.  Can I ask, once again, for a 'null' keyword?

-- David R. Tribble, dtribble@technologist.com --



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






Author: Ron Natalie <ron@sensor.com>
Date: 1998/12/08
Raw View
Steve Clamage wrote:

>
> As they should. A constraint on dynamic_cast is that the expresison
> in parentheses have pointer type if the type in brackets is a
> pointer type. A literal zero is not a pointer, and so the
> code is not valid.
>
A literal zero is a null pointer constant.  Moreover, the spec
requires that if the cast is to a pointer, the null pointer should
be converted.

The compilers that don't convert this are WRONG.



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






Author: "Robert Stafford" <stafford@bindview.com>
Date: 1998/12/08
Raw View

Siemel Naran wrote in message ...
>
>On 8 Dec 1998 00:05:34 GMT, Robert Stafford <stafford@bindview.com> wrote:
>
>>Should the following compile? (C has a virtual function.)
>>
>>C* c = dynamic_cast<C*>(0);
>
>What are you trying to do?

I was asked why this expression would not compile.   The obvious answer is
that a literal zero is not a pointer, but is merely convertible to a pointer
to any type and automatic type conversions do not make sense when applied to
the argument of a dynamic_cast (sort of a pre-cast cast - huh?)  The
question then was posed that if 0 is convertible to a pointer of any type,
and if the obvious result of the expression (if it were allowed) does not
depend on the type, shouldn't the expression be allowed?  It may be that the
expression was the result of a pre-processor substitution, but I don't know
that for a fact.



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






Author: AllanW@my-dejanews.com
Date: 1998/12/08
Raw View
In article <74hr05$l17$1@engnews2.Eng.Sun.COM>,
  stephen.clamage@sun.com (Steve Clamage) wrote:
>
> "Robert Stafford" <stafford@bindview.com> writes:
>
> >Should the following compile? (C has a virtual function.)
>
> >C* c = dynamic_cast<C*>(0);
>
> >MSVC 6.0 complains about a dynamic cast of a const int while EGCS 1.1
> >complains about a dynamic cast of an int.
>
> As they should. A constraint on dynamic_cast is that the expresison
> in parentheses have pointer type if the type in brackets is a
> pointer type. A literal zero is not a pointer, and so the
> code is not valid.

      4.10 Pointer conversions                              [conv.ptr]

   1 A null pointer constant is an integral constant expression (5.19)
     rvalue of integer type that evaluates to zero. ...

A null pointer constant is not a pointer?

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


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






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/08
Raw View
sbnaran@localhost.localdomain.COM (Siemel Naran) writes:

>On 8 Dec 1998 00:05:34 GMT, Robert Stafford <stafford@bindview.com> wrote:

>>Should the following compile? (C has a virtual function.)
>>
>>C* c = dynamic_cast<C*>(0);

>Como gives the following weird error:

>"a.c", line 3: error: the operand of a pointer dynamic_cast must be a pointer
>          to a complete class type
>  int main() { C* c = dynamic_cast<C*>(0); }
                                      ^
I wouldn't characterize that as a weird error message.
The standard says about dynamic_cast<T>(v):

"If T is a pointer type, v shall be an rvalue of a pointer to
complete class type"

It seems to me that this compiler (maybe "Comeau"?) is exactly right.

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


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






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/08
Raw View
Ron Natalie <ron@sensor.com> writes:

>Steve Clamage wrote:

>> As they should. A constraint on dynamic_cast is that the expresison
>> in parentheses have pointer type if the type in brackets is a
>> pointer type. A literal zero is not a pointer, and so the
>> code is not valid.
>>
>A literal zero is a null pointer constant.  Moreover, the spec
>requires that if the cast is to a pointer, the null pointer should
>be converted.

>The compilers that don't convert this are WRONG.

I don't think so. Some relevant quotes:

"4.10 Pointer conversions
A null pointer constant is an integral constant expression (5.19)
rvalue of integer type that evaluates to zero. A null pointer
constant can be converted to a pointer type; the result is the null
pointer value of that type..."

Notice that a null pointer constant (e.g. a literal zero) is
an integer value, not a pointer value. It can be converted
implicitly or explicitly to a pointer value.

"5.2.7 Dynamic cast
The result of the expression dynamic_cast<T>(v) is the result of
converting the expression v to type T. ...
If T is a pointer type, v shall be an rvalue of a pointer to complete
class type ..." This section goes on to allow null pointer values
for expression v.

In the original example, dynamic_cast<C*>(0), expression v does
not have pointer type, and so the expression is invalid.

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


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






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/08
Raw View
AllanW@my-dejanews.com writes:

>In article <74hr05$l17$1@engnews2.Eng.Sun.COM>,
>  stephen.clamage@sun.com (Steve Clamage) wrote:

>> "Robert Stafford" <stafford@bindview.com> writes:

>> >Should the following compile? (C has a virtual function.)

>> >C* c = dynamic_cast<C*>(0);

>> >MSVC 6.0 complains about a dynamic cast of a const int while EGCS 1.1
>> >complains about a dynamic cast of an int.

>> As they should. A constraint on dynamic_cast is that the expresison
>> in parentheses have pointer type if the type in brackets is a
>> pointer type. A literal zero is not a pointer, and so the
>> code is not valid.

>      4.10 Pointer conversions                              [conv.ptr]

>   1 A null pointer constant is an integral constant expression (5.19)
>     rvalue of integer type that evaluates to zero. ...

>A null pointer constant is not a pointer?

Correct. Notice what you quoted: The null pointer constant is an
rvalue of integer type. The paragraph goes on to say that it
can be converted to a pointer value. It does not say that it IS
a pointer value.

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


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






Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/12/08
Raw View
On 8 Dec 1998 17:49:23 GMT, Steve Clamage <stephen.clamage@sun.com> wrote:
>sbnaran@localhost.localdomain.COM (Siemel Naran) writes:

>>Como gives the following weird error:
>
>>"a.c", line 3: error: the operand of a pointer dynamic_cast must be a pointer
>>          to a complete class type
>>  int main() { C* c = dynamic_cast<C*>(0); }
>>                                       ^

>I wouldn't characterize that as a weird error message.
>The standard says about dynamic_cast<T>(v):
>
>"If T is a pointer type, v shall be an rvalue of a pointer to
>complete class type"
>
>It seems to me that this compiler (maybe "Comeau"?) is exactly right.

To me, a more meaningful error message would have been to replace the
word "complete" with "uniquely defined".  Since '0' on its own means
all pointers -- X*, Y*, std::vector<int>*, etc -- it is not a pointer
to a uniquely defined type.

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






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/09
Raw View
Siemel Naran wrote:

> On 8 Dec 1998 17:49:23 GMT, Steve Clamage <stephen.clamage@sun.com> wrote:
> >sbnaran@localhost.localdomain.COM (Siemel Naran) writes:

> >>Como gives the following weird error:
> >
> >>"a.c", line 3: error: the operand of a pointer dynamic_cast must be a pointer
> >>          to a complete class type
> >>  int main() { C* c = dynamic_cast<C*>(0); }
> >>                                       ^

> >I wouldn't characterize that as a weird error message.
> >The standard says about dynamic_cast<T>(v):
> >
> >"If T is a pointer type, v shall be an rvalue of a pointer to
> >complete class type"
> >
> >It seems to me that this compiler (maybe "Comeau"?) is exactly right.

> To me, a more meaningful error message would have been to replace the
> word "complete" with "uniquely defined".  Since '0' on its own means
> all pointers -- X*, Y*, std::vector<int>*, etc -- it is not a pointer
> to a uniquely defined type.

0 is an integer, not a pointer. It's convertible to a null pointer of
any type, but it is not itself a pointer. It is a null pointer constant,
but by an oddity of the standard's terminology, it isn't a null pointer.



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






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/09
Raw View
Robert Stafford wrote:
>
> Siemel Naran wrote in message ...
> >
> >On 8 Dec 1998 00:05:34 GMT, Robert Stafford <stafford@bindview.com> wrote:
> >
> >>Should the following compile? (C has a virtual function.)
> >>
> >>C* c = dynamic_cast<C*>(0);
> >
> >What are you trying to do?
>
> I was asked why this expression would not compile.   The obvious answer is
> that a literal zero is not a pointer, but is merely convertible to a pointer
> to any type and automatic type conversions do not make sense when applied to
> the argument of a dynamic_cast (sort of a pre-cast cast - huh?)  The
> question then was posed that if 0 is convertible to a pointer of any type,
> and if the obvious result of the expression (if it were allowed) does not
> depend on the type, shouldn't the expression be allowed?  It may be that the
> expression was the result of a pre-processor substitution, but I don't know
> that for a fact.

So would you say the compiler should accept the following code?

#include <iostream>

int f(long) { return 0; }
int f(short) { return 0; }

int main()
{
  std::cout << f(1) << std::endl;
}

There are two possibilities: f(short) and f(long). But both give
the same result. So it doesn't really matter which one is called.
Probably even the generated code would be identical in both cases
(if the compiler inlines the call).


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






Author: "Robert Stafford" <stafford@bindview.com>
Date: 1998/12/08
Raw View
Should the following compile? (C has a virtual function.)

C* c = dynamic_cast<C*>(0);

MSVC 6.0 complains about a dynamic cast of a const int while EGCS 1.1
complains about a dynamic cast of an int.

Granted, the compiler could not know what kind of pointer to convert 0 to,
but the value for a failed cast is the same as the only rational value for a
successful cast (static_cast<C*>(0)) so the actual pointer type used for the
'0' is irrelevant for the value of the cast.




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






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/08
Raw View
"Robert Stafford" <stafford@bindview.com> writes:

>Should the following compile? (C has a virtual function.)

>C* c = dynamic_cast<C*>(0);

>MSVC 6.0 complains about a dynamic cast of a const int while EGCS 1.1
>complains about a dynamic cast of an int.

As they should. A constraint on dynamic_cast is that the expresison
in parentheses have pointer type if the type in brackets is a
pointer type. A literal zero is not a pointer, and so the
code is not valid.

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


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






Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/12/08
Raw View
On 8 Dec 1998 00:05:34 GMT, Robert Stafford <stafford@bindview.com> wrote:

>Should the following compile? (C has a virtual function.)
>
>C* c = dynamic_cast<C*>(0);

The type of the argument of the dynamic_cast is not known -- it could
be any pointer.  Why not just use this:
  C * c=0;

If the type of the argument of the dynamic_cast is known and this type
is compatible with the result type, the result is garaunteed to exist.
  C * c=dynamic_cast<C*>(static_cast<C*>(0)); // same as above example


>MSVC 6.0 complains about a dynamic cast of a const int while EGCS 1.1
>complains about a dynamic cast of an int.

Como gives the following weird error:

"a.c", line 3: error: the operand of a pointer dynamic_cast must be a pointer
          to a complete class type
  int main() { C* c = dynamic_cast<C*>(0); }
                                       ^


>Granted, the compiler could not know what kind of pointer to convert 0 to,
>but the value for a failed cast is the same as the only rational value for a
>successful cast (static_cast<C*>(0)) so the actual pointer type used for the
>'0' is irrelevant for the value of the cast.

What are you trying to do?

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