Topic: What is the macro NULL according to standard C++?


Author: David R Tribble <david@tribble.com>
Date: 2000/11/27
Raw View
Nick Maclaren wrote:
> [...], making NULL a keyword prevents it being
> tested for existence as a macro, and that is very common.  A
> HUGE number of programs have headers that include lines like:
>
>     #ifndef NULL
>     #define NULL 0
>     #endif
>
> It is the obvious way to provide K&R/ISO compatibility in this
> area.

NULL could be both a keyword and a macro:

    #define NULL  NULL

This would allow NULL to be a keyword with special properties, and
also allow preprocessor tests like what you show above.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/11/16
Raw View
James Kuyper wrote:

[...]

> > Someone (I think it was James Kuyper, but I may be wrong) proposed to
> > make NULL a keyword.  That *is* an improvement.
>
> I can't claim the credit; I was merely describing a highly impractical
> (given the need for backward compatibility) suggestion that someone else
> made a long time ago. NULL being a keyword isn't impractical in itself,
> but the whole point of making it a keyword is to give it special
> handling. Unfortunately, that special handling can't, at this point,
> include making it illegal to use NULL in integer contexts - there's too
> much legacy code that relies on it.

Really?
I guess there's much legacy code which relies on 0 being a null
pointer constant, but I cannot imagine that there is much code
which relies on NULL being usable in integer contexts.
Why should someone write NULL, if all he means is 0 (which is
typed much easier, and doesn't need a header). Moreover, everyone
comping from C will avoid that anyway, since in C NULL can be
((void*)0), which cannot be used in integer contexts.

Of course, the only way to find out for sure would be to
examine code, but I would be surprised if there were even
more than 10 C++ programs in the whole world, which
intentionally use NULL in an integer context (conformance
testers excluded, of course), and the number of programs
doing that by accident should not be very large, too (and
are not unlikely to be broken anyway).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: nmm1@cus.cam.ac.uk (Nick Maclaren)
Date: 2000/11/16
Raw View
In article <3A13F739.72C55869@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
|> James Kuyper wrote:
|>
|> > > Someone (I think it was James Kuyper, but I may be wrong) proposed to
|> > > make NULL a keyword.  That *is* an improvement.
|> >
|> > I can't claim the credit; I was merely describing a highly impractical
|> > (given the need for backward compatibility) suggestion that someone else
|> > made a long time ago. NULL being a keyword isn't impractical in itself,
|> > but the whole point of making it a keyword is to give it special
|> > handling. Unfortunately, that special handling can't, at this point,
|> > include making it illegal to use NULL in integer contexts - there's too
|> > much legacy code that relies on it.
|>
|> Really?
|> I guess there's much legacy code which relies on 0 being a null
|> pointer constant, but I cannot imagine that there is much code
|> which relies on NULL being usable in integer contexts.
|> Why should someone write NULL, if all he means is 0 (which is
|> typed much easier, and doesn't need a header). Moreover, everyone
|> comping from C will avoid that anyway, since in C NULL can be
|> ((void*)0), which cannot be used in integer contexts.

An attempt at being abstract.  Or even just plain perversity.
I have certainly seen C code use NULL to initialise a mixture
of pointer and integer static variables, with all appearances
of it being a deliberate decision.  And I have seen it done by
accident many times - and done it myself!

Equally seriously, making NULL a keyword prevents it being
tested for existence as a macro, and that is very common.  A
HUGE number of programs have headers that include lines like:

    #ifndef NULL
    #define NULL 0
    #endif

It is the obvious way to provide K&R/ISO compatibility in this
area.

|> Of course, the only way to find out for sure would be to
|> examine code, but I would be surprised if there were even
|> more than 10 C++ programs in the whole world, which
|> intentionally use NULL in an integer context (conformance
|> testers excluded, of course), and the number of programs
|> doing that by accident should not be very large, too (and
|> are not unlikely to be broken anyway).

I should be surprised if there were as FEW as 10 C programs
which use NULL as an integer initialiser, even restricting it
to those that did it more-or-less deliberately.  And I should
be VERY surprised if there were fewer than thousands that rely
on it without realising that they do so.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email:  nmm1@cam.ac.uk
Tel.:  +44 1223 334761    Fax:  +44 1223 334679

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/11/16
Raw View
Christopher Eltschka wrote:
> I guess there's much legacy code which relies on 0 being a null
> pointer constant, but I cannot imagine that there is much code
> which relies on NULL being usable in integer contexts.
> Why should someone write NULL, if all he means is 0 (which is
> typed much easier, and doesn't need a header).

Because that someone mistakenly believes that NULL also specifies
the character code for the NUL character, e.g.,

    memset(buf, NULL, sizeof(buf));

This is real code I've seen.  The tragedy is that many C compilers,
including many Unix C compilers, accept this without complaint.
Fortunately, it's not portable C code.

But the real tragedy is that this is perfectly valid and portable
C++ code.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Andrew J Robb" <news.@.screaming.net@news.server.worldonline.co.uk>
Date: 2000/11/16
Raw View
>What we can do is define a new type of null pointer constant (either
>__null, or (void*)0, or whatever), in addition to 0, and require that
>NULL be defined as this new type.  Programs which use 0 will continue to
>work as before; programs which use NULL only as a pointer will get
>additional type protection, and programs which use NULL as an int will
>break.  IMHO, we can afford to break the latter.

Don't forget that the ISO C++ standard explicitly forbids NULL from being
(void*)0.
--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/11/17
Raw View
Christopher Eltschka wrote:
>
> James Kuyper wrote:
>
> [...]
>
> > > Someone (I think it was James Kuyper, but I may be wrong) proposed to
> > > make NULL a keyword.  That *is* an improvement.
> >
> > I can't claim the credit; I was merely describing a highly impractical
> > (given the need for backward compatibility) suggestion that someone else
> > made a long time ago. NULL being a keyword isn't impractical in itself,
> > but the whole point of making it a keyword is to give it special
> > handling. Unfortunately, that special handling can't, at this point,
> > include making it illegal to use NULL in integer contexts - there's too
> > much legacy code that relies on it.
>
> Really?
> I guess there's much legacy code which relies on 0 being a null
> pointer constant, but I cannot imagine that there is much code
> which relies on NULL being usable in integer contexts.
> Why should someone write NULL, if all he means is 0 (which is
> typed much easier, and doesn't need a header). Moreover, everyone
> comping from C will avoid that anyway, since in C NULL can be
> ((void*)0), which cannot be used in integer contexts.

Agreed; my comment was mostly aimed at C++. I'd forgotten for a moment
that this was cross-posted to both newsgroups, or I would have qualified
my statement somewhat.

> Of course, the only way to find out for sure would be to
> examine code, but I would be surprised if there were even
> more than 10 C++ programs in the whole world, which
> intentionally use NULL in an integer context (conformance

I earn my living at C, not C++, so I haven't seen it myself. However,
from what I've heard on comp.std.c++, it's a moderately common practice.
It's fully legal within the C++ context, however much you or I might
look down on such 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Stephen Baynes <stephen.baynes@soton.sc.philips.com>
Date: 2000/11/20
Raw View
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Nick Maclaren wrote:

> |> Of course, the only way to find out for sure would be to
> |> examine code, but I would be surprised if there were even
> |> more than 10 C++ programs in the whole world, which
> |> intentionally use NULL in an integer context (conformance
> |> testers excluded, of course), and the number of programs
> |> doing that by accident should not be very large, too (and
> |> are not unlikely to be broken anyway).
>
> I should be surprised if there were as FEW as 10 C programs
> which use NULL as an integer initialiser, even restricting it
> to those that did it more-or-less deliberately.  And I should
> be VERY surprised if there were fewer than thousands that rely
> on it without realising that they do so.

I expect there are a lot of people who think that because their
compiler accepts it, it must be OK. And having seen another person do
it, they assume it is an acceptable and desirable 'clever' C idiom
that they should also follow.


--
Stephen Baynes    CEng  MBCS                Stephen.Baynes@soton.sc.philips.com
Philips Semiconductors Ltd
Southampton SO15 0DJ                        +44 (0)23 80316431 *** NEW ***
United Kingdom                              My views are my 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/11/20
Raw View
Your newsreader (or a server somwhere) is broken.  It split the long
References: field and added a blank line, which explains the changed
subject.

"Gary Hinger" <garyh@zipperint.com> writes:
> I thought that the NUL character is defined as character 0.

True, but irrelevant.  What matters for C is that the null terminating
character (which need not be called NUL) has value 0.

> Are you suggesting - in theory or in practice - that there are
> implementations where strings are terminated by characters other
> than (char)NULL?

In C, NULL need not be of integer type.  Remember that this thread is
crossposted, and that the message you were responding to explicitly
talked about C, not C++.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/11/11
Raw View
Gabriel Dos Reis wrote:
>
> prj@po.cwru.edu (Paul Jarc) writes:
...
> | Wrong.  The following is a conforming definition of NULL:
> | #ifdef __cplusplus
> |   int const __null=0;
> | #else
> |   enum { __null };
> | #endif
> | #define NULL (+__null)
>
> What exactly is wrong?
>
> The above definition of NULL isn't a C++ conforming definition.  To
> see why, again consider Fergus' program in
> <8trav1$o32$1@mulga.cs.mu.OZ.AU>.

As I said nearly a week ago (or so I thought - in reality, my message
showed up on the newsgroup only three minutes before yours), Fergus'
stringizing argument doesn't work with (+__null), because (+__null) is a
perfectly legal null pointer constant. Therefore, it's a perfectly legal
expansion to provide for NULL.

> | Without magic, an implementation is allowed to do this: (+__null) is
> | an rvalue integer constant expression with value 0, and thus an
> | eligible null pointer constant.
>
> No, without magic that an implementation isn't allowed to do that.
> The semantics you gain from
>
>         int const __null = 0;
>
> (as a null pointer constant) is something that happens *after* the
> preprocessing phase.  That can't work.  Sorry.

I'm afraid I don't follow what you're saying there. The fact that
(+__null) is a completely legal null pointer constant is, as you say,
not recognised until after preprocessing. However, there's no need for
it to be.

...
> Someone (I think it was James Kuyper, but I may be wrong) proposed to
> make NULL a keyword.  That *is* an improvement.

I can't claim the credit; I was merely describing a highly impractical
(given the need for backward compatibility) suggestion that someone else
made a long time ago. NULL being a keyword isn't impractical in itself,
but the whole point of making it a keyword is to give it special
handling. Unfortunately, that special handling can't, at this point,
include making it illegal to use NULL in integer contexts - there's too
much legacy code that relies on it. The best that can be done now is to
allow for a warning in such contexts, and the warning can just as easily
be tied to (+__null) as to NULL itself.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/11/10
Raw View
Gabriel Dos Reis wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> [...]
>
> | ... However, the suggestion of
> | defining it as (+__null) gets around that problem, and requires far less
> | magic than simply defining NULL as __null without providing a
> | declaration for __null.
>
> There is still a need to special case the identifier `__null' in the
> preprocessor or else Fergus's program
> (<8trav1$o32$1@mulga.cs.mu.OZ.AU>) will output the wrong answer.

I don't know how to locate a message using that reference. However, I
was able to locate it by more brute force method. Fergus's program was:

        #define STRINGIZE(x) STRINGIZE_2(x)
        #define STRINGIZE_2(x) #x

        #include <stdio.h>

        int main(void) {
                puts(STRINGIZE(NULL));
                return 0;
        }

This would produce a problem only if (+__null) weren't a legal null
pointer constant. However, (+__null) was very carefully chosen to be a
legal null pointer constant. Therefore, there's nothing non-conforming
about an implementation using it as the expansion of NULL.

> Now, by the time you summarize all the places where one needs to
> special case __null, you'll realize that Paul's suggestion (or
> Fergus's) doesn't require less magic than just putting directly the
> magic with NULL or with an identifier not declared in the C++ sense.

Option 1: (+__null), where __null has already been given a declaration
that makes (+__null) a legal null pointer constant.
Option 2: __null, where __null is a special keyword.

Where are special cases needed to handle option 1, that aren't also
needed to handle option 2? There's at least one point where option 2
requires special handling, and option 1 doesn't: the point where the
compiler checks whether an identifier has ever been declared before it's
first use.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/11/10
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

>I wrote:
>>   int const __null=0;
>
>I suppose that should be static.  That's orthogonal to the discussion,
>though.

In C++, the `const' here implies `static'.

 |   7.1.1 - Storage class specifiers [dcl.stc]
 |
 | -6- A name declared in a namespace scope without a storage-class-specifier has external
 |    linkage unless it has internal linkage because of a previous declaration and provided it
 |    is not declared const.  Objects declared const and not explicitly declared extern have
 |    internal linkage.

This is one of those incompatibilities between C and C++.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: 2000/11/10
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| > prj@po.cwru.edu (Paul Jarc) writes:
| > | [Special casing NULL in the preprocessor, not just the compiler]
| > | would be (somewhat) harder, because it would require more special
| > | casing.
| >
| > I disagree.  That wouldn't be harder unless you don't pay attention to
| > conformance.  See Fergus' program in <8trav1$o32$1@mulga.cs.mu.OZ.AU>.
|
| Wrong.  The following is a conforming definition of NULL:
| #ifdef __cplusplus
|   int const __null=0;
| #else
|   enum { __null };
| #endif
| #define NULL (+__null)

What exactly is wrong?

The above definition of NULL isn't a C++ conforming definition.  To
see why, again consider Fergus' program in
<8trav1$o32$1@mulga.cs.mu.OZ.AU>.

| Without magic, an implementation is allowed to do this: (+__null) is
| an rvalue integer constant expression with value 0, and thus an
| eligible null pointer constant.

No, without magic that an implementation isn't allowed to do that.
The semantics you gain from

 int const __null = 0;

(as a null pointer constant) is something that happens *after* the
preprocessing phase.  That can't work.  Sorry.

[...]

| > Secondly, there are better alternatives to require magic from the part
| > of implementations for improving the language.
|
| I can't think of any better way to make *this* improvement.  If you
| can, let's hear it.

If you can't "think of any better way to make *this* improvement",
maybe it is because what you see as an improvement isn't really an
improvement.

Someone (I think it was James Kuyper, but I may be wrong) proposed to
make NULL a keyword.  That *is* an improvement.
My personal view is to introduce a distinct type (say __null_type__)
with the ability to convert to any pointer type and to say that NULL
is a macro which evalutes to an rvalue expression of `__null_type__'
type and convertible to null pointer.

| > | ...  The standards are bound by backward
| > | compatibility, so they can't force this change.
| >
| > C99 demonstrated the contrary: the C language was changed so that
| > `long long' is the largest integer type in C, contrary to the promise
| > C90 made.
|
| Yes, but hopefully we won't be able to rely on the committee's
| willingness to break such promises again.

That is a statement radically different from what you said earlier and
to which I replied.

| > By earlier suggestion, I understood your suggestion: [...]
| > Did you understand something else?
|
| It wasn't me you were replying to there.

Aha?  Fair enough.  James Kuyper was pointing me to
"the earlier suggestion" from which I understood your

 int const __null = 0;

Then, you jumped in (replying to my posting) saying:

 I think there may be a misunderstanding about the referent of "the
 earlier suggestion".

So, to make things clear, I explicitly stated what I understood by
"the earlier suggestion".  Now you're replying with:

 It wasn't me you were replying to there.

If you do really feel so, why did you jump in the first place?
No answer needed: we're getting off-topic.

Let's keep the debate to technical material relevant to these groups.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/11/10
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> The semantics you gain from
>
>  int const __null = 0;
>
> (as a null pointer constant) is something that happens *after* the
> preprocessing phase.

So what?  The null pointer constant semantics *always* take effect
only after preprocessing.  NULL doesn't have to be recognizable as a
null pointer constant to the preprocessor itself - the preprocessor is
incapable of recognizing even 0 as a null pointer constant anyway,
since it has no idea what a null pointer constant is.  All that
matters is that the definition of NULL must be an rvalue null pointer
constant, and a program that stringizes it must not be able to prove
otherwise (such as by printing the stringization).  (+__null)
satisfies these requirements.  A program can't necessarily prove by
examining the stringization that NULL *is* a null pointer constant,
but that's not needed.

> Someone (I think it was James Kuyper, but I may be wrong) proposed to
> make NULL a keyword.  That *is* an improvement.

It would be impractical for the standards to make such a change, and
difficult for implementations to do so without the standards: it
requires more magic than (+__null) does.

> My personal view is to introduce a distinct type (say __null_type__)
> with the ability to convert to any pointer type and to say that NULL
> is a macro which evalutes to an rvalue expression of `__null_type__'
> type and convertible to null pointer.

If we were starting from scratch, that would be a good way to go.  But
starting from C or C++, 0 must be retained, and it already has all the
special handling that would be required for __null_type__, so there's
not much point.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: comeau@panix.com (Greg Comeau)
Date: 2000/11/07
Raw View
In article <8u8ake$1jgu$1@nntp1.ba.best.com>,
C. M. Heard <heard@vvnet.com> wrote:
>James Kanze wrote:
>[ ... ]
>>> | > Yes.  It was qualified as an "abomination" when used to
>>> | > designate a nullary function (for example int main(void)), cf
>>> | > "D&E".
>[ ... ]
>>That use of void is illegal in C++, and always has been (at least
>>since the first edition of the "C++ Programming Language ").  C++ has
>>never allowed functions without prototypes, so there was never any
>>problem of backward compatibility of f().  When C adopted the C++
>>prototypes, of course, making f() mean that the function took no
>>parameters would have broken just about every C program in existance.
>
>Always has been?  I don't think so;  it was legal in CD2 (8.3.5,2):
>
>  If the parameter-declaration-clause is empty, the function  takes  no
>  arguments.   The parameter  list  (void)  is  equivalent  to  the empty
>  parameter list.
>
>If indeed it's illegal, it apparently was made so after CD2.

int main(void).... is just fine, at least accto the standard.
See http://www.comeaucomputing.com/techtalk/#voidmain for
both useful and useless info about this.

- Greg
--
Comeau Computing / Comeau C/C++ "so close" 4.2.44 betas NOW AVAILABLE
TRY Comeau C++ ONLINE at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James.Kanze@dresdner-bank.com
Date: 2000/11/07
Raw View
In article <8u8ake$1jgu$1@nntp1.ba.best.com>,
  "C. M. Heard" <heard@vvnet.com> wrote:
> James Kanze wrote:
> [ ... ]
> >> | > Yes.  It was qualified as an "abomination" when used to
> >> | > designate a nullary function (for example int main(void)), cf
> >> | > "D&E".
> [ ... ]
> >That use of void is illegal in C++, and always has been (at least
> >since the first edition of the "C++ Programming Language ").  C++
> >has never allowed functions without prototypes, so there was never
> >any problem of backward compatibility of f().  When C adopted the
> >C++ prototypes, of course, making f() mean that the function took
> >no parameters would have broken just about every C program in
> >existance.

> Always has been?  I don't think so; it was legal in CD2 (8.3.5,2):

>   If the parameter-declaration-clause is empty, the function takes
>   no arguments.  The parameter list (void) is equivalent to the
>   empty parameter list.

> If indeed it's illegal, it apparently was made so after CD2.

Sorry, I'm confusing coding guidelines and the standard.  It has never
been necessary in C++, and I've never actually seen it used in C++,
however.  I presume it is supported for reasons of C compatibility.
Whereas it is very necessary in C, since there is no other way of
declaring a function with no parameters.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/11/08
Raw View
David R Tribble <david@tribble.com> writes:
>> Using NULL at least has the benefits of 1) looking like a null
>> pointer, even if it really isn't underneath, and 2) standing a
>> better chance of continuing to compile if NULL ever becomes a real
>> type-safe null pointer constant and 0 becomes just an int.

Jame Kanze <kanze@gabi-soft.de> wrote:
> Realistically, there will never be a time when 0 will not convert
> implicitly to a null pointer.  About the best we can hope for is a
> real null, which *if* used might prevent some errors, and would
> certainly be more readable.  I don't think it reasonable to require
> all existing code to be modified to use this new feature, however.

Even if a future standard were to disallow 0 as null, there's nothing
to prevent future compilers to provide a switch that would allow it
(presumably for all that broken existing code).

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/11/08
Raw View
"David R Tribble" <david@tribble.com> wrote
>> The addition of a new keyword or special identifier (e.g., 'null',
>> '__null__', or simply 'NULL') for both C and C++ has been suggested
>> several times in the past.  But no one seems convinced or moved
>> enough to actually get this into the language.  (C++ needs it far
>> more than C.)

"Balog Pal" <pasa@lib.hu> writes:
>> I'd definitely vote in favour.
>>
>> I think some of the actual voters are present her, thet could
>> enlighten why such a specialised npc would be bad.

prj@po.cwru.edu (Paul Jarc) writes:
> I'm not one of them, but implementations are already free to do this:
>   enum { __null__ };
>   #define NULL __null__

This doesn't solve the problem, since NULL would still have an
integer type.

To solve all the type safety and ambiguity issues for NULL in C++,
NULL must have a pointer type.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/11/08
Raw View
Paul Jarc wrote:
> The following is a conforming definition of NULL:
> #ifdef __cplusplus
>   int const __null=0;
> #else
>   enum { __null };
> #endif
> #define NULL (+__null)
>
> Without magic, an implementation is allowed to do this: (+__null) is
> an rvalue integer constant expression with value 0, and thus an
> eligible null pointer constant.  If magic is added to generate
> warnings only, then conformance is not affected.  With this
> definition, the desired warnings require no magic in the preprocessor.

But, as is, the definition of NULL above doesn't solve the problem
of disllowing the use of NULL as an integer.  We desire that code
like the following to be invalid:

    int i = NULL;

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/11/08
Raw View
David R Tribble <david@tribble.com> writes:
> Paul Jarc wrote:
> > #define NULL (+__null)
>
> But, as is, the definition of NULL above doesn't solve the problem
> of disllowing the use of NULL as an integer.

Well, of course not.  You need magic for that, but it can be done
purely in code generation and not preprocessing.  Just trigger a
warning whenever +__null is used in non-pointer context.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: 2000/11/08
Raw View
On Wed,  8 Nov 2000 18:20:19 GMT, David R Tribble <david@tribble.com> wrote:
> Paul Jarc wrote:
> > The following is a conforming definition of NULL:
> > #ifdef __cplusplus
> >   int const __null=0;
> > #else
> >   enum { __null };
> > #endif
> > #define NULL (+__null)
> >
> > Without magic, an implementation is allowed to do this: (+__null) is
> > an rvalue integer constant expression with value 0, and thus an
> > eligible null pointer constant.  If magic is added to generate
> > warnings only, then conformance is not affected.  With this
> > definition, the desired warnings require no magic in the preprocessor.
>
> But, as is, the definition of NULL above doesn't solve the problem
> of disllowing the use of NULL as an integer.  We desire that code
> like the following to be invalid:
>
>     int i = NULL;

For this to be invalid, the standard(s) would have to be changed. The
whole thread was about how to enable a conforming implementation to warn
about misuses of NULL within the current standard(s).

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Fri, 3 Nov 2000 16:37:16 GMT
Raw View
fjh@cs.mu.OZ.AU (Fergus Henderson) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
|
| >prj@po.cwru.edu (Paul Jarc) writes:
| >
| >| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| >| > If we were to talk about magic, then why don't think the
| >| > implementation will put the magic in NULL itself as an identifier?
| >|
| >| It's still required to be a macro, so its definition is what must be
| >| magical.
| >
| >The *observable behaviour* requires it to behave as if defined as a
| >macro.
|
| Right.  But that behaviour includes the results of stringizing it
| with the `#' operator, testing it with `#if defined', etc.
| Also many implementations use a separate preprocessor.

Quite right.  But the observable behaviour is the behaviour of a
completely translated program -- not just that of a preprocessed
program.  Which means that an implementation which decides to special
case NULL can't just do so without taking special actions in the
preprocessing phase.  The crux of the problem is that Paul's
suggestion (or yours) is using semantics formally not understood by
the preprocessor -- as you're showing in your example below.  So, to
make the whole magic work properly there ought to be a way of special
casing NULL in the preprocessor.

| So typically it will be much easier to implement this by just defining
| NULL as a macro, e.g.
|
|  #define NULL __null
| or
|  #define NULL (+__null)
|
| and adding the special treatment for `__null' at a later phase in the
| compiler, rather than treating NULL itself as magic whenever the
| appropriate header file has been included.  This is how it is done
| in the GNU C++ / glibc implementation.

Yes, I know it is done in the GNU C++ compiler.  But the way it is
done in that compiler isn't satisfying, as you noted.

I'm not disputing the fact that it is much easier to feature in a non
conformant manner ;-)

Seriously, you're giving arguments for why an implementation which is
special casing NULL in its core part should do so in the preprocessor.

| But because of the possibility of macro stringization with `#', this
| technique only works if `__null' is a possible null pointer constant.

Or if the implementation (in the preprocessor) pays attention to
constructs which would reveal the internal definition as a non null
pointer constant.

| Otherwise someone could write the program
|
|  #define STRINGIZE(x) STRINGIZE_2(x)
|  #define STRINGIZE_2(x) #x
|
|  #include <stdio.h>
|
|  int main(void) {
|   puts(STRINGIZE(NULL));
|   return 0;
|  }

Contrary to two attemps posted on this thread, this program is
technically valid and shows why it does not suffice to special case
__null in the core part of an implementation.

| and then if this program outputs `__null', they could complain that
| the compiler wasn't conforming, since `__null' can't be a null pointer
| constant.
|
| Hence it makes sense to discuss whether `#define NULL __null' would be
| valid.  As someone pointed out, NULL must expand to an rvalue, and in
| C++ (unlike C) there's no way for `__null' to be an rvalue of integer type.
| So I think in C++ `#define NULL __null' is not a valid implementation,
| and so if the above program outputs `__null', then the implementation is
| not conforming.

100% agreed.  But your analysis is an argument for also special casing
__null in the preprocessor.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Sat, 4 Nov 2000 00:05:31 GMT
Raw View
I wrote:
>   int const __null=0;

I suppose that should be static.  That's orthogonal to the discussion,
though.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/11/04
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:

>James Kuyper <kuyper@wizard.net> writes:
>
>| ... However, the suggestion of
>| defining it as (+__null) gets around that problem, and requires far less
>| magic than simply defining NULL as __null without providing a
>| declaration for __null.
>
>There is still a need to special case the identifier `__null' in the
>preprocessor or else Fergus's program
>(<8trav1$o32$1@mulga.cs.mu.OZ.AU>) will output the wrong answer.

No, if the implementation defines NULL as

 #define NULL (+__null)

then there is no need for it to special case `__null' in the
preprocessor.  On such an implementation, the program that I posted
earlier will output "(+__null)", but that is a perfectly valid output
for that program.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/11/04
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:

 >fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
 >
 >| So typically it will be much easier to implement this by just defining
 >| NULL as a macro, e.g.
 >|
 >|  #define NULL __null
 >| or
 >|  #define NULL (+__null)
 >|
 >| and adding the special treatment for `__null' at a later phase in the
 >| compiler, rather than treating NULL itself as magic whenever the
 >| appropriate header file has been included.  This is how it is done
 >| in the GNU C++ / glibc implementation.
 >
 >Yes, I know it is done in the GNU C++ compiler.  But the way it is
 >done in that compiler isn't satisfying, as you noted.

The reason that this isn't completely satisfying is because it isn't
conforming.  But if the GNU C++ implementation defined NULL as
`(+__null)' rather than as `__null', and still issued the same
warnings (i.e. taking care to not warn about the first application of
unary + to __null), then it would be both conforming and satisfying.

 >|  #define STRINGIZE(x) STRINGIZE_2(x)
 >|  #define STRINGIZE_2(x) #x
 >|
 >|  #include <stdio.h>
 >|
 >|  int main(void) {
 >|   puts(STRINGIZE(NULL));
 >|   return 0;
 >|  }
 >
 >Contrary to two attemps posted on this thread, this program is
 >technically valid and shows why it does not suffice to special case
 >__null in the core part of an implementation.

In C (note this thread is still crossposted), it does suffice to
special case `__null' in the core part of an implementation.
For C, `__null' is one of the many possible valid outputs for this
program, since in C

 enum { __null }
 #define NULL __null

would be a valid definition of NULL.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: 2000/11/05
Raw View
James Kuyper <kuyper@wizard.net> writes:

[...]

| Could you give an example of legal code whose behavior depends upon NULL
| not being an lvalue?

A conforming implementation does not only have to accept valid
programs; it has also to emit diagnostics for invalid C++ constructs.
That was my point.
Off hand, I can't show youu a valid C++ program which depends on NULL
not being an lvalue and I don't think I could -- it is harder to
provide conter-example than to prove something is well-formed
according to C++ rules :-)

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/11/05
Raw View
"Gary Hinger" <garyh@zipperint.com> writes:

>Why not use this definition
>
>extern struct Null
>{
>    template <typename T> operator T*(){return 0;}
>    Null operator+() const {return *this;}
>
>    /* Don't define this. We want to prevent implicit conversion to int. */
>    /*
>        bool operator() const {return false;}
>    */
>    bool operator!() const {return true;}
>
>    /* Now define operator== and operator!= applied to Null and T*...
>        ...
>    */
>} const __null;
>
>#define NULL (+__null)
...
>the only problem is that "if (NULL)" won't compile... Otherwise it seems
>functional for all practical purposes.

That would not be conforming, since NULL does not expand to a null
pointer constant.

Conversion from NULL (defined as above) to a pointer type will use up
your one allowed user-defined conversion per implicit conversion
sequence.  So that definition of NULL will fail for examples like this
one:

 struct Foo {
  Foo(int *p) {}
 };

 void bar(Foo) {}

 int main() {
  bar(NULL); // NULL -> int * -> Foo requires two
    // user-defined conversions
 }

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/11/06
Raw View
Gabriel Dos Reis wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> [...]

[Re: int const __null;
     #define NULL __null]

> | Could you give an example of legal code whose behavior depends upon NULL
> | not being an lvalue?
>
> A conforming implementation does not only have to accept valid
> programs; it has also to emit diagnostics for invalid C++ constructs.
> That was my point.

OK, I guess you're right. The statement

 const int *pi = &NULL;

should produce a diagnostic with any legal definition of NULL, and that
would require special-casing by the implementation with this definition
of NULL.
However, I still believe that defining NULL as (+__null) would require
no special casing, not even for stringizing, since it is a null pointer
constant.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James.Kanze@dresdner-bank.com
Date: 2000/11/06
Raw View
In article <flhf5rl6sy.fsf@sel.cmla.ens-cachan.fr>,
  Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> wrote:
> James.Kanze@dresdner-bank.com writes:

> | In article <m33dheb1xr.fsf@merlin.codesourcery.com>,
> |   Gabriel Dos Reis <gdr@merlin.codesourcery.com> wrote:
> | > kanze@gabi-soft.de writes:

> | > [...]

> | > | I'm not sure, but isn't void a C++ innovation that was adopted
> | > | by C?

> | > Yes.  It was qualified as an "abomination" when used to
> | > designate a nullary function (for example int main(void)), cf
> | > "D&E".

> | *That* use of void is definitly an innovation of the C standards
> | committee, and post-dates C++, since it is only relevant because of
> | the introduction of C++ function prototypes in C.

> That use of void was a C++ invention, later adopted by the C
> committees.

That use of void is illegal in C++, and always has been (at least
since the first edition of the "C++ Programming Language ").  C++ has
never allowed functions without prototypes, so there was never any
problem of backward compatibility of f().  When C adopted the C++
prototypes, of course, making f() mean that the function took no
parameters would have broken just about every C program in existance.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James.Kanze@dresdner-bank.com
Date: 2000/11/06
Raw View
In article <39FF5E42.7483E909@tribble.com>,
  David R Tribble <david@tribble.com> wrote:
> fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
> >>  That is fine and good.  But why did he decide to make `(void *)0'
> >>  not be a null pointer constant?  It can't have been for reasons
> >>  of type safety, since allowing `(void *)0' as a null pointer
> >>  constant would make things more type-safe, not less type-safe.

> kanze@gabi-soft.de wrote:
> > I'm just guessing, but I'd guess that it was because at the time
> > "(void*)0" wasn't a null pointer constant in C either, at least on
> > the machines Stroustrup was using.  K&R 1 don't mention the
> > possibility.  (Rather understandably, since the language they are
> > defining doesn't have void.)

> That maybe explains why Stroustrup didn't allow a special case for
> '((void*)0)', but it doesn't explain why the ISO C++ committee
> didn't consider it (many years later).

The ISO C++ did consider it, many years later.  They voted against
it.  I'm not well situated to give the arguments against it, since I
was the author of the proposal.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "C. M. Heard" <heard@vvnet.com>
Date: 2000/11/07
Raw View
James Kanze wrote:
[ ... ]
>> | > Yes.  It was qualified as an "abomination" when used to
>> | > designate a nullary function (for example int main(void)), cf
>> | > "D&E".
[ ... ]
>That use of void is illegal in C++, and always has been (at least
>since the first edition of the "C++ Programming Language ").  C++ has
>never allowed functions without prototypes, so there was never any
>problem of backward compatibility of f().  When C adopted the C++
>prototypes, of course, making f() mean that the function took no
>parameters would have broken just about every C program in existance.

Always has been?  I don't think so;  it was legal in CD2 (8.3.5,2):

  If the parameter-declaration-clause is empty, the function  takes  no
  arguments.   The parameter  list  (void)  is  equivalent  to  the empty
  parameter list.

If indeed it's illegal, it apparently was made so after CD2.

//cmh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: 2000/11/07
Raw View
James Kuyper <kuyper@wizard.net> writes:

[...]

| However, I still believe that defining NULL as (+__null) would require
| no special casing, not even for stringizing, since it is a null pointer
| constant.

I believe you are right but I need to think about it more than I've
done ;-)

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: Fri, 3 Nov 2000 01:11:15 GMT
Raw View
Gabriel Dos Reis wrote:
...
> No, that is not true.  The earlier suggestion requires more special
> casings than you seem to believe.  It makes NULL an lvalue expression
> of int type, so (for example) it renders the following construct
> technically valid
>
>      const void* p = &NULL;
>
> which is invalid according to C++ semantics.  So to catch such
> constructs, the implementation still needs more than what you're
> stating.

You're right - while a conforming implementation can legally accept such
a program, it does require a diagnostic, which means the test for __null
is needed more widely than I was thinking. However, the suggestion of
defining it as (+__null) gets around that problem, and requires far less
magic than simply defining NULL as __null without providing a
declaration for __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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: 2000/11/03
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| > C++ semantics say __null, as defined above, is an lvalue, but Paul is
| > suggesting the implementation need not let the program use that.
|
| I suggested that only as one possible way to satisfy the rvalue
| requirement.  Fergus's (+__null) is a better suggestion, as it
| requires less magic.

Yes, Fergus' (+__null) is better than yours but still suffers from the
preprocessor `#' operator unless a special action is taken by the
preprocessor.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/11/03
Raw View
Gabriel Dos Reis wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> | Gabriel Dos Reis wrote:
> | ...
> | > C/C++ semantics: if I understand your objection correctly __null won't
> | > be subjected to C/C++ semantics; so there is no point in discussing it
> | > here.
> |
> | That was not the suggestion at all.
>
> In <m31ywwakj1.fsf@merlin.codesourcery.com> I said :
>
>         |  >  int const __null=0;
>         |  >  #define NULL __null
>         |  >Would this work?
>         |
>         | Yes, that would work fine.
>
>         No, it isn't fine:  Now NULL is an lvalue.
>
> To which Paul objected (<m3itq7iryj.fsf@multivac.student.cwru.edu>):
>
>         The implementation knows it's an lvalue, but it need not
>         reveal that to programs.

That objection did not occur on this branch of the thread, and I wasn't
speaking directly to that issue. I ignored it because it seems to me
that any use that depended upon the lvalue-ness would be a syntax or
constraint violation of some kind. I was in any event implicitly
assuming the modification which someone else suggested, that it be
changed to (+__null). I should have said so explicitly; my apologies.

Could you give an example of legal code whose behavior depends upon NULL
not being an lvalue? Stringizing and then parsing the macro would be one
way to find out, but it's quite tricky to write strictly conforming C
code that depends upon the contents of a stringization of NULL. C++ only
has the concept of "well-formed" code, rather than "strictly conforming"
code, so it's a little easier for C++, but let's ignore all examples
based upon stringizing the macro. I suppose the answer could be
different in C and C++. Since this is cross-posted to both newsgroups,
if you choose to provide an example, please identify which standard your
example is intended for.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: 2000/11/03
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| > James Kuyper <kuyper@wizard.net> writes:
| > | Gabriel Dos Reis wrote:
| > | > is pointless.  For example
| > | >
| > | >         #define NULL __null
| > | >
| > | > would suffice and work.  Note there is no definition of __null (in C++
| > |
| > | This would require magic, because it would require supressing the normal
| > | requirements that such an identifier be declared before use.
| >
| > But that wouldn't harder than the scenario you described above: it is
| > just about special case handling of the identifier `__null'.
|
| It would be (somewhat) harder, because it would require more special
| casing.

I disagree.  That wouldn't be harder unless you don't pay attention to
conformance.  See Fergus' program in <8trav1$o32$1@mulga.cs.mu.OZ.AU>.

| ...  Of course arbitrary magic is *possible*,

Taking care of __null being correctly handled in the preprocessor
isn't arbitrary magic.

| ... but methods that
| require less special casing are more likely to be adopted by
| implementors voluntarily, and in this case, that's our only option for
| improving the language.

Firstly, on comp.std.c++ or comp.std.c we should be seeking for
conformant methods.
Secondly, there are better alternatives to require magic from the part
of implementations for improving the language.

| ...  The standards are bound by backward
| compatibility, so they can't force this change.

C99 demonstrated the contrary: the C language was changed so that
`long long' is the largest integer type in C, contrary to the promise
C90 made.  The standards can state whatever they like, provided there
is sufficent agreement to vote on.

| > | ... The
| > | advantage of the earlier suggestion is that it requires no such special
| > | casing at any point other than in the part of the compiler that produces
| > | the warning messages.
| >
| > No, that is not true.  The earlier suggestion requires more special
| > casings than you seem to believe.
|
| I think there may be a misunderstanding about the referent of "the
| earlier suggestion".

By earlier suggestion, I understood your suggestion:

  Are const objects integral constant expressions in C++?
    int const __null=0;
    #define NULL __null
  Would this work?

Did you understand something else?

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/11/03
Raw View
James Kuyper <kuyper@wizard.net> writes:
> Gabriel Dos Reis wrote:
> > prj@po.cwru.edu (Paul Jarc) writes:
> ...
> > | definition of NULL.  Maybe you were thinking of something like this:
> > |   #include <stdlib.h>
> > |   #include <string.h>
> > |   #define SS(x) #x
> > |   #define S(x)  SS(x)
> > |   int main() {
> > |     if (strcmp(S(NULL), "__null")==0)
> > |       if (__null!=0)
> >
> > But yours is using an identifier whose meaning is implementation
> > defined.  I don't see why it is more conforming that the original
> > program.
>
> You're correct; the second if() should be changed to
>
>  if (NULL!=0)

Well, that brings it into conformance, but also makes it useless.  I
realize now that Niklas's original program was useful and conforming
(for C++); I had misunderstood what it was supposed to do.  It tests
for the illegal "__null" definition of NULL.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/11/03
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> prj@po.cwru.edu (Paul Jarc) writes:
> | [Special casing NULL in the preprocessor, not just the compiler]
> | would be (somewhat) harder, because it would require more special
> | casing.
>
> I disagree.  That wouldn't be harder unless you don't pay attention to
> conformance.  See Fergus' program in <8trav1$o32$1@mulga.cs.mu.OZ.AU>.

Wrong.  The following is a conforming definition of NULL:
#ifdef __cplusplus
  int const __null=0;
#else
  enum { __null };
#endif
#define NULL (+__null)

Without magic, an implementation is allowed to do this: (+__null) is
an rvalue integer constant expression with value 0, and thus an
eligible null pointer constant.  If magic is added to generate
warnings only, then conformance is not affected.  With this
definition, the desired warnings require no magic in the preprocessor.

A program can stringize NULL and parse the results, but that doesn't
present any problems, because (+__null) is a legal null pointer
constant anyway.

> Firstly, on comp.std.c++ or comp.std.c we should be seeking for
> conformant methods.

And here we have one.

> Secondly, there are better alternatives to require magic from the part
> of implementations for improving the language.

I can't think of any better way to make *this* improvement.  If you
can, let's hear it.

> | ...  The standards are bound by backward
> | compatibility, so they can't force this change.
>
> C99 demonstrated the contrary: the C language was changed so that
> `long long' is the largest integer type in C, contrary to the promise
> C90 made.

Yes, but hopefully we won't be able to rely on the committee's
willingness to break such promises again.

> By earlier suggestion, I understood your suggestion: [...]
> Did you understand something else?

It wasn't me you were replying to there.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Gary Hinger" <garyh@zipperint.com>
Date: Fri, 3 Nov 2000 15:30:26 GMT
Raw View
Why not use this definition

extern struct Null
{
    template <typename T> operator T*(){return 0;}
    Null operator+() const {return *this;}

    /* Don't define this. We want to prevent implicit conversion to int. */
    /*
        bool operator() const {return false;}
    */
    bool operator!() const {return true;}

    /* Now define operator== and operator!= applied to Null and T*...
        ...
    */
} const __null;

#define NULL (+__null)

Then the compiler will automatically complain without any "magic":

int i = NULL; /* Not allowed, can't convert from Null to int */
int const *p = &NULL; /* Not allowed, operator& applied to temporary */

the only problem is that "if (NULL)" won't compile... Otherwise it seems
functional for all practical purposes.

Paul Jarc <prj@po.cwru.edu> wrote in message
news:m3em0xas50.fsf@multivac.student.cwru.edu...
> Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> > prj@po.cwru.edu (Paul Jarc) writes:
> > | Are const objects integral constant expressions in C++?
> > |   int const __null=0;
> > |   #define NULL __null
> > | Would this work?
> >
> > Yes.  But what is the difference with 0?
>
> The idea is for the implementation to complain when __null is used as
> an integer.  You wouldn't want 0 to elicit that same complaint.
>
>
> paul
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
> [ Note that the FAQ URL has changed!  Please update your bookmarks.     ]
>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Fri, 3 Nov 2000 15:30:59 GMT
Raw View
Gabriel Dos Reis wrote:
>
> prj@po.cwru.edu (Paul Jarc) writes:
...
> | definition of NULL.  Maybe you were thinking of something like this:
> |   #include <stdlib.h>
> |   #include <string.h>
> |   #define SS(x) #x
> |   #define S(x)  SS(x)
> |   int main() {
> |     if (strcmp(S(NULL), "__null")==0)
> |       if (__null!=0)
>
> But yours is using an identifier whose meaning is implementation
> defined.  I don't see why it is more conforming that the original
> program.

You're correct; the second if() should be changed to

 if (NULL!=0)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Fri, 3 Nov 2000 15:32:10 GMT
Raw View
James Kuyper <kuyper@wizard.net> writes:

[...]

| ... However, the suggestion of
| defining it as (+__null) gets around that problem, and requires far less
| magic than simply defining NULL as __null without providing a
| declaration for __null.

There is still a need to special case the identifier `__null' in the
preprocessor or else Fergus's program
(<8trav1$o32$1@mulga.cs.mu.OZ.AU>) will output the wrong answer.

Now, by the time you summarize all the places where one needs to
special case __null, you'll realize that Paul's suggestion (or
Fergus's) doesn't require less magic than just putting directly the
magic with NULL or with an identifier not declared in the C++ sense.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: Thu, 2 Nov 2000 05:12:33 GMT
Raw View
On Wed,  1 Nov 2000 21:56:55 GMT, Gabriel Dos Reis <gdr@merlin.codesource=
ry.com> wrote:
> James Kuyper <kuyper@wizard.net> writes:
> | Gabriel Dos Reis wrote:
> | > prj@po.cwru.edu (Paul Jarc) writes:
> | ...
> | > | Are const objects integral constant expressions in C++?
> | > |   int const __null=3D0;
> | > |   #define NULL __null
> | > | Would this work?
[=B7=B7=B7]
> I was under the impression that the above definition was intended to
> replace 0 without any intervening magic.  But if we were to talk about
> magic then actually, anything the implementation likes will work (as
> far as it takes of care of observable behaviour) and the whole thread
> is pointless.  For example =20
>=20
>  #define NULL __null
>=20
> would suffice and work.  Note there is no definition of __null (in C++
> sense) (There is at least one implementation which handle NULL in that
> special way). The implementation may not even have to define NULL as a
> macro.=20

There's still the issue of whether a program inspecting the expansion of
NULL =E0 la

   #include <stdlib.h>
   #include <string.h>

   #define SS(x)  #x
   #define S(x)   SS(x)

   int main() {
      return strcmp(S(NULL), "__null") ? EXIT_SUCCESS : EXIT_FAILURE;
   }

may notice such a definition on a conforming implementation.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Thu, 2 Nov 2000 05:12:56 GMT
Raw View
Gabriel Dos Reis wrote:
...
> C/C++ semantics: if I understand your objection correctly __null won't
> be subjected to C/C++ semantics; so there is no point in discussing it
> here.

That was not the suggestion at all. It would be subject to all the same
semantics as any other file scope identifier of a const 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Thu, 2 Nov 2000 05:13:31 GMT
Raw View
Gabriel Dos Reis wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> | kanze@gabi-soft.de wrote:
> | >
> | > Team-Rocket@gmx.net (Niklas Matthies) writes:
> | ...
> | > That, of course, argues for a special key word.  Which is probably the
                                    ^^^^^^^^^^^^^^^^
> | > best solution anyway.  But it requires a bit of effort -- if f is a
> | > template function, what type should f(NULL) instantiate?
> |
> | That shouldn't be a difficult decision to make. It should be either
> | void* or ambiguous,
>
> Well, I have some trouble following the decisive argument which makes it
> that void* should be selected.  The Standard says NULL is of integer type
> (but doesn't mention which one).

The context of this suggestion is that NULL be made a special keyword.
The whole point of the keyword approach is that the keyword should be
implicitly convertable to a null pointer of any type, just as NPCs are
now, and that it not be usable as an integer (or at least, for backwards
compatibility, that it should generate a warning when so used). It would
be contrary to the whole point of this suggestion for f(NULL) to
instantiate f(T) if T is an integer type. I also don't see how it could
could unambiguously instantiate f(T*) for any T other than 'void'. I
could see an argument for it being an error.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Thu, 2 Nov 2000 14:41:51 GMT
Raw View
Gabriel Dos Reis wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> | Gabriel Dos Reis wrote:
> | >
> | > prj@po.cwru.edu (Paul Jarc) writes:
> | ...
> | > | Are const objects integral constant expressions in C++?
> | > |   int const __null=0;
> | > |   #define NULL __null
> | > | Would this work?
> | >
> | > Yes.  But what is the difference with 0?
> |
> | Sometimes 0 is intended to be a NULL pointer, sometimes it's meant to be
> | an integer. This suggestion would be to make it easy for an
> | implementation to distinguish those two cases, and provide a warning
> | when NULL is used in a context that calls for an integer, and also when
> | any other form of 0 is used in a context that calls for a pointer.
>
> How?  Special treatment, I presume.  But then, if the implementation is
> going to do black magic, it doesn't need to define __null to be of
> integer type at all.

What black magic? Whenever it finds a __null in a context calling for an
integer, it gives a warning (by the time it knows that the context
requires an integer type, the NULL has already been pre-processed to
__null). Whenever it finds any expression of integer type other than
"__null" being used in a pointer context it gives a warning. No fancy
magic there.

...
> is pointless.  For example
>
>         #define NULL __null
>
> would suffice and work.  Note there is no definition of __null (in C++

This would require magic, because it would require supressing the normal
requirements that such an identifier be declared before use. The
advantage of the earlier suggestion is that it requires no such special
casing at any point other than in the part of the compiler that produces
the warning messages. Other than those warning messages, __null would be
a perfectly ordinary identifier, that happens to fall in the reserved
namespace, following all the ordinary rules covering a file scope
identifier for a const 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Thu, 2 Nov 2000 14:51:25 GMT
Raw View
James Kuyper <kuyper@wizard.net> writes:

| Gabriel Dos Reis wrote:
| ...
| > C/C++ semantics: if I understand your objection correctly __null won't
| > be subjected to C/C++ semantics; so there is no point in discussing it
| > here.
|
| That was not the suggestion at all.

In <m31ywwakj1.fsf@merlin.codesourcery.com> I said :

 |  >  int const __null=0;
 |  >  #define NULL __null
 |  >Would this work?
 |
 | Yes, that would work fine.

 No, it isn't fine:  Now NULL is an lvalue.

To which Paul objected (<m3itq7iryj.fsf@multivac.student.cwru.edu>):

 The implementation knows it's an lvalue, but it need not
 reveal that to programs.

C++ semantics say __null, as defined above, is an lvalue, but Paul is
suggesting the implementation need not let the program use that.

Notice that Fergus recognized the problem and proposed a solution
inside C++ -- that is much more interesting than invoking suddenly an
extaordinary implementation capability.  At least for comp.std.c++,
comp.std.c.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Dennis Ritchie <dmr@bell-labs.com>
Date: Thu, 2 Nov 2000 15:53:34 GMT
Raw View

Ron Natalie wrote:

> James.Kanze@dresdner-bank.com wrote:
> > Are you sure?  I don't remember it in PCC around 86/87, but I could be
> > mistaken.  And it *was* in "The C++ Programming Language", first
> > edition.

> PCC was certainly far from state of the art.  Void's showed up certainly
> by the Version 7 PDP-11 compiler (and probably in the phototypesetter
> compiler, but my memory is really hazy on that).  This was back around 1978!
> I remeber chasing bugs in the implementation of voids certainly before 1981.

My memory (unconstrained by documentation) would want to agree with Ron
that the void type was in the works by 7th Edition Unix, but when I look at
the actual distributions, it wasn't there yet.  Nor is it in 32V.  It does show
up by the early 1980s in various C compilers, including my PDP-11 one as well
as PCC, in both AT&T and Berkeley distributions.

 Dennis

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Thu, 2 Nov 2000 17:13:33 GMT
Raw View
Team-Rocket@gmx.net (Niklas Matthies) writes:

| On Wed,  1 Nov 2000 21:56:55 GMT, Gabriel Dos Reis <gdr@merlin.codesource=
| ry.com> wrote:
| > James Kuyper <kuyper@wizard.net> writes:
| > | Gabriel Dos Reis wrote:
| > | > prj@po.cwru.edu (Paul Jarc) writes:
| > | ...
| > | > | Are const objects integral constant expressions in C++?
| > | > |   int const __null=3D0;
| > | > |   #define NULL __null
| > | > | Would this work?
| [=B7=B7=B7]
| > I was under the impression that the above definition was intended to
| > replace 0 without any intervening magic.  But if we were to talk about
| > magic then actually, anything the implementation likes will work (as
| > far as it takes of care of observable behaviour) and the whole thread
| > is pointless.  For example =20
| >=20
| >  #define NULL __null
| >=20
| > would suffice and work.  Note there is no definition of __null (in C++
| > sense) (There is at least one implementation which handle NULL in that
| > special way). The implementation may not even have to define NULL as a
| > macro.=20
|
| There's still the issue of whether a program inspecting the expansion of
| NULL =E0 la
|
|    #include <stdlib.h>
|    #include <string.h>
|
|    #define SS(x)  #x
|    #define S(x)   SS(x)
|
|    int main() {
|       return strcmp(S(NULL), "__null") ? EXIT_SUCCESS : EXIT_FAILURE;

What semantics do you expect from this construct?

|    }
|
| may notice such a definition on a conforming implementation.

How?  If the implementation is able to do magic with NULL why can't it
catch such usage?  If it can't, then it is an error in the
implementation.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Thu, 2 Nov 2000 17:39:33 GMT
Raw View
Team-Rocket@gmx.net (Niklas Matthies) writes:
>    #include <stdlib.h>
>    #include <string.h>
>
>    #define SS(x)  #x
>    #define S(x)   SS(x)
>
>    int main() {
>       return strcmp(S(NULL), "__null") ? EXIT_SUCCESS : EXIT_FAILURE;
>    }

That's not a strictly conforming program; it depends on a particular
definition of NULL.  Maybe you were thinking of something like this:
  #include <stdlib.h>
  #include <string.h>
  #define SS(x) #x
  #define S(x)  SS(x)
  int main() {
    if (strcmp(S(NULL), "__null")==0)
      if (__null!=0)
        return EXIT_FAILURE;
    return EXIT_SUCCESS;
  }


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: Thu, 2 Nov 2000 17:51:20 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:

>prj@po.cwru.edu (Paul Jarc) writes:
>
>| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
>| > If we were to talk about magic, then why don't think the
>| > implementation will put the magic in NULL itself as an identifier?
>|
>| It's still required to be a macro, so its definition is what must be
>| magical.
>
>The *observable behaviour* requires it to behave as if defined as a
>macro.

Right.  But that behaviour includes the results of stringizing it
with the `#' operator, testing it with `#if defined', etc.
Also many implementations use a separate preprocessor.
So typically it will be much easier to implement this by just defining
NULL as a macro, e.g.

 #define NULL __null
or
 #define NULL (+__null)

and adding the special treatment for `__null' at a later phase in the
compiler, rather than treating NULL itself as magic whenever the
appropriate header file has been included.  This is how it is done
in the GNU C++ / glibc implementation.

But because of the possibility of macro stringization with `#', this
technique only works if `__null' is a possible null pointer constant.
Otherwise someone could write the program

 #define STRINGIZE(x) STRINGIZE_2(x)
 #define STRINGIZE_2(x) #x

 #include <stdio.h>

 int main(void) {
  puts(STRINGIZE(NULL));
  return 0;
 }

and then if this program outputs `__null', they could complain that
the compiler wasn't conforming, since `__null' can't be a null pointer
constant.

Hence it makes sense to discuss whether `#define NULL __null' would be
valid.  As someone pointed out, NULL must expand to an rvalue, and in
C++ (unlike C) there's no way for `__null' to be an rvalue of integer type.
So I think in C++ `#define NULL __null' is not a valid implementation,
and so if the above program outputs `__null', then the implementation is
not conforming.

In particular, the egcs-1.1.2 GNU C++ compiler on Linux with
libc-2.1.2 is not conforming.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: Thu, 2 Nov 2000 17:58:25 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:

>James Kuyper <kuyper@wizard.net> writes:
>
>| kanze@gabi-soft.de wrote:
>| >
>| > Team-Rocket@gmx.net (Niklas Matthies) writes:
>| ...
>| > That, of course, argues for a special key word.  Which is probably the
>| > best solution anyway.  But it requires a bit of effort -- if f is a
>| > template function, what type should f(NULL) instantiate?
>|
>| That shouldn't be a difficult decision to make. It should be either
>| void* or ambiguous,
>
>Well, I have some trouble following the decisive argument which makes it
>that void* should be selected.  The Standard says NULL is of integer type
>(but doesn't mention which one).

We're talking here about what should happen *if* NULL were defined to be
a special keyword.

You're right that currently NULL must be of an integer type, and so
with the current rules, for `template <class T> void f(T)', a call to
`f(NULL)' will instantatiate `f' with some integer type.
But that is unlikely to be what the programmer intended!
So if we're going to use a keyword rather than a macro for NULL,
we should make sure that it does something more reasonable in this
case.  I think either of the two approaches suggested above would be OK.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Thu, 2 Nov 2000 18:39:24 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Team-Rocket@gmx.net (Niklas Matthies) writes:
| >    #include <stdlib.h>
| >    #include <string.h>
| >
| >    #define SS(x)  #x
| >    #define S(x)   SS(x)
| >
| >    int main() {
| >       return strcmp(S(NULL), "__null") ? EXIT_SUCCESS : EXIT_FAILURE;
| >    }
|
| That's not a strictly conforming program; it depends on a particular
| definition of NULL.  Maybe you were thinking of something like this:
|   #include <stdlib.h>
|   #include <string.h>
|   #define SS(x) #x
|   #define S(x)  SS(x)
|   int main() {
|     if (strcmp(S(NULL), "__null")==0)
|       if (__null!=0)

But yours is using an identifier whose meaning is implementation
defined.  I don't see why it is more conforming that the original
program.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Thu, 2 Nov 2000 18:39:46 GMT
Raw View
James Kuyper <kuyper@wizard.net> writes:

| Gabriel Dos Reis wrote:
| >
| > James Kuyper <kuyper@wizard.net> writes:
| >
| > | Gabriel Dos Reis wrote:
| > | >
| > | > prj@po.cwru.edu (Paul Jarc) writes:
| > | ...
| > | > | Are const objects integral constant expressions in C++?
| > | > |   int const __null=0;
| > | > |   #define NULL __null
| > | > | Would this work?
| > | >
| > | > Yes.  But what is the difference with 0?
| > |
| > | Sometimes 0 is intended to be a NULL pointer, sometimes it's meant to be
| > | an integer. This suggestion would be to make it easy for an
| > | implementation to distinguish those two cases, and provide a warning
| > | when NULL is used in a context that calls for an integer, and also when
| > | any other form of 0 is used in a context that calls for a pointer.
| >
| > How?  Special treatment, I presume.  But then, if the implementation is
| > going to do black magic, it doesn't need to define __null to be of
| > integer type at all.
|
| What black magic? Whenever it finds a __null in a context calling for an
| integer, it gives a warning (by the time it knows that the context
| requires an integer type, the NULL has already been pre-processed to
| __null). Whenever it finds any expression of integer type other than
| "__null" being used in a pointer context it gives a warning. No fancy
| magic there.

The black magic here is the fact to handle a particular expression of
type int depending on its spelling.  As said Paul, call it whatever
you like.

| > is pointless.  For example
| >
| >         #define NULL __null
| >
| > would suffice and work.  Note there is no definition of __null (in C++
|
| This would require magic, because it would require supressing the normal
| requirements that such an identifier be declared before use.

But that wouldn't harder than the scenario you described above: it is
just about special case handling of the identifier `__null'.

| ... The
| advantage of the earlier suggestion is that it requires no such special
| casing at any point other than in the part of the compiler that produces
| the warning messages.

No, that is not true.  The earlier suggestion requires more special
casings than you seem to believe.  It makes NULL an lvalue expression
of int type, so (for example) it renders the following construct
technically valid

     const void* p = &NULL;

which is invalid according to C++ semantics.  So to catch such
constructs, the implementation still needs more than what you're
stating.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: Thu, 2 Nov 2000 18:41:13 GMT
Raw View
On Thu,  2 Nov 2000 17:13:33 GMT, Gabriel Dos Reis <gdr@merlin.codesource=
ry.com> wrote:
> Team-Rocket@gmx.net (Niklas Matthies) writes:
> | On Wed,  1 Nov 2000 21:56:55 GMT, Gabriel Dos Reis <gdr@merlin.codeso=
urce=3D
> | ry.com> wrote:
[=B7=B7=B7]
> | > I was under the impression that the above definition was intended t=
o
> | > replace 0 without any intervening magic.  But if we were to talk ab=
out
> | > magic then actually, anything the implementation likes will work (a=
s
> | > far as it takes of care of observable behaviour) and the whole thre=
ad
> | > is pointless.  For example =3D20
> | >=3D20
> | >  #define NULL __null
> | >=3D20
> | > would suffice and work.  Note there is no definition of __null (in =
C++
> | > sense) (There is at least one implementation which handle NULL in t=
hat
> | > special way). The implementation may not even have to define NULL a=
s a
> | > macro.=3D20
> |=20
> | There's still the issue of whether a program inspecting the expansion=
 of
> | NULL =3DE0 la
> |=20
> |    #include <stdlib.h>
> |    #include <string.h>
> |=20
> |    #define SS(x)  #x
> |    #define S(x)   SS(x)
> |=20
> |    int main() {
> |       return strcmp(S(NULL), "__null") ? EXIT_SUCCESS : EXIT_FAILURE;
>=20
> What semantics do you expect from this construct?
>=20
> |    }
> |=20
> | may notice such a definition on a conforming implementation.
>=20
> How?  If the implementation is able to do magic with NULL why can't it
> catch such usage?

Of course it can. But the magic would have to be in the preprecessor if
the implementation uses one, which is the proponents of __null want to
avoid. If we felt comfortable with putting magic in the preprocessor, we
wouldn't have to bother with __null in the first place.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Douglas A. Gwyn" <gwyn@arl.army.mil>
Date: Thu, 2 Nov 2000 18:42:18 GMT
Raw View
Ron Natalie wrote:
> "Douglas A. Gwyn" wrote:
> > if(p)... enshrined the behavior in the C language forever.
> So was if(p == -1), Doug.

That was an error indication, resulting from a jump to a common
error-return thunk in the PDP-11 UNIX C library, and so far as I
recall was never called a "null pointer" by anyone nor guaranteed
to work by K&R etc.  Indeed, we spent a lot of effort trying to
cope with the legacy -1 "value" for certain pointers in established
APIs, especially SIG_ERR, and I would hate to think of the vastly
greater effort it would take to go through all currently existing
source code to change the (currently guaranteed) null-pointer
behavior of C.

This can serve as yet another lesson to apply when designing a
new language, but it's too late to "fix" this for C.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Douglas A. Gwyn" <gwyn@arl.army.mil>
Date: Thu, 2 Nov 2000 18:54:36 GMT
Raw View
kanze@gabi-soft.de wrote:
> Most early Unix implementations did just that.  You could pass NULL as
> the source to strcpy, and you would get an empty string.

That was an accident of *one* specific implementation, BSD UNIX
on the VAX.  It wasn't true for the PDP-11.

> I've talked to people who thought that this was guaranteed behavior.

No doubt there are plenty of idiots in the world.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: Thu, 2 Nov 2000 18:54:42 GMT
Raw View
On Thu,  2 Nov 2000 17:39:33 GMT, Paul Jarc <prj@po.cwru.edu> wrote:
> Team-Rocket@gmx.net (Niklas Matthies) writes:
> >    #include <stdlib.h>
> >    #include <string.h>
> >
> >    #define SS(x)  #x
> >    #define S(x)   SS(x)
> >
> >    int main() {
> >       return strcmp(S(NULL), "__null") ? EXIT_SUCCESS : EXIT_FAILURE;
> >    }
>
> That's not a strictly conforming program; it depends on a particular
> definition of NULL.

It's not strictly conforming, but the standard (fortunately) imposes
requirements on implementations also for the compilation and executioin
of non-strictly conforming programs.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Thu, 2 Nov 2000 19:22:05 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> James Kuyper <kuyper@wizard.net> writes:
> | Gabriel Dos Reis wrote:
> | > is pointless.  For example
> | >
> | >         #define NULL __null
> | >
> | > would suffice and work.  Note there is no definition of __null (in C++
> |
> | This would require magic, because it would require supressing the normal
> | requirements that such an identifier be declared before use.
>
> But that wouldn't harder than the scenario you described above: it is
> just about special case handling of the identifier `__null'.

It would be (somewhat) harder, because it would require more special
casing.  Of course arbitrary magic is *possible*, but methods that
require less special casing are more likely to be adopted by
implementors voluntarily, and in this case, that's our only option for
improving the language.  The standards are bound by backward
compatibility, so they can't force this change.

> | ... The
> | advantage of the earlier suggestion is that it requires no such special
> | casing at any point other than in the part of the compiler that produces
> | the warning messages.
>
> No, that is not true.  The earlier suggestion requires more special
> casings than you seem to believe.

I think there may be a misunderstanding about the referent of "the
earlier suggestion".  The point is that it's best to get the job done
with as little special casing as possible, all else being equal.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Thu, 2 Nov 2000 21:54:45 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> C++ semantics say __null, as defined above, is an lvalue, but Paul is
> suggesting the implementation need not let the program use that.

I suggested that only as one possible way to satisfy the rvalue
requirement.  Fergus's (+__null) is a better suggestion, as it
requires less magic.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: Wed, 1 Nov 2000 16:44:08 GMT
Raw View
In article <04II5.2973$UL.177740@bgtnsc07-news.ops.worldnet.att.net>,
  "David Thompson" <david.thompson1@worldnet.att.net> wrote:
> <kanze@gabi-soft.de> wrote :
> ....
> > You're thinking of C (where there are no rvalues).  In C++, an
> > expression is either an lvalue or an rvalue, and there is an
> > lvalue to rvalue conversion (implicit, of course).

> C certainly does have rvalues and lvalues the same as C++, with an
> implicit conversion: C89 6.2.2.1; C99 6.3.2.1p2,3.  C does not have
> _user-defined_ conversions.

I just verified in C99, and you are right.  The wording is different,
but the rules are pretty much the same as in C++.  I don't have C89
handy to compare, but my memory was that the term rvalue never
appeared in the standard -- the results of an expression either were
or were not an lvalue.  But perhaps my memory is wrong, and I am
thinking of K&R 1.  At some point, lvalue-ness was just a property
which an expression could have or not; rvalue wasn't needed as a term,
because all expressions had that property.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: Wed, 1 Nov 2000 16:44:12 GMT
Raw View
In article <39F0B9DA.F0C816E@localhost.localdomain>,
  AJRobb@REMOVE.bigfoot.com.screaming.net wrote:

> I searched the ISO/IEC-14482:1998 standard and found no reference to
> NULL except within the C library.  So unless you are using the
> standard C library, you do not have access to a definition of NULL.

You must include <cstddef> to have access to NULL.  So?

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: Wed, 1 Nov 2000 16:44:25 GMT
Raw View
In article <39FDDACB.D1611B02@sensor.com>,
  Ron Natalie <ron@sensor.com> wrote:

> kanze@gabi-soft.de wrote:

> > I'm not sure, but isn't void a C++ innovation that was adopted by
> > C?

> Nope, might have been some cross fertilization, but void showed up
> in C before C with classes existed.

Are you sure?  I don't remember it in PCC around 86/87, but I could be
mistaken.  And it *was* in "The C++ Programming Language", first
edition.

> > I'd also bet that the definition of a null pointer constant in the
> > ARM was written before (void*)0 was a legal null pointer constant
> > in C. Or simply copied from text that was written before.

> The C89 spec predates the ARM by a year.

The copyright on the ARM is 1990, the copyright on C89 is 1989.  Both,
however, contain large parts that were written earlier.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: Wed, 1 Nov 2000 16:44:34 GMT
Raw View
In article <IZoHKtASaK95EwVN@ntlworld.com>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
> In article <86r95acej1.fsf@gabi-soft.de>, kanze@gabi-soft.de writes

> >Well, the above is certainly the most frequent case.  Before void*,
> >of course, most C compilers allowed implicit conversions between
> >all pointer types, precisely so that the above would not need a
> >cast.

> Not any C compiler that I ever used (or at least not in any mode
> that I would have used it) Implicit conversions of pointers is pure
> poison.

You're too young:-).  PCC and the original K&R C compiler both allowed
it.  In K&R 1, it is described as incorrect, but it is also stated
that the compiler won't complain.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: Wed, 1 Nov 2000 16:44:43 GMT
Raw View
In article <m33dheb1xr.fsf@merlin.codesourcery.com>,
  Gabriel Dos Reis <gdr@merlin.codesourcery.com> wrote:
> kanze@gabi-soft.de writes:

> [...]

> | I'm not sure, but isn't void a C++ innovation that was adopted by
> | C?

> Yes.  It was qualified as an "abomination" when used to designate a
> nullary function (for example int main(void)), cf "D&E".

*That* use of void is definitly an innovation of the C standards
committee, and post-dates C++, since it is only relevant because of
the introduction of C++ function prototypes in C.

I think that C++ had void* before C as well, but I'm less certain.

> | I'd also bet that the definition of a null pointer constant in the
> | ARM was written before (void*)0 was a legal null pointer constant
> | in C. Or simply copied from text that was written before.

> Well, actually Bjarne (and M. Ellis) discussed explicitly the
> "void*" stuff in ARM (page 36) and refered to C as "ANSI C".

The copyright of the ARM is later than the C standard, and people were
talking about ANSI C before the formal adoption anyway (much as was
the case with C++).  Much of the formal specification of C++ in the
ARM, however, is word for word identical with the formal specification
in the documentation of earlier versions of CFront.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Wed, 1 Nov 2000 16:46:45 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> Well, if the implementation can add more magic, why should it go the
> trouble to define __null as above?

The suggestion was based on the supposition that it's easier to add
magic to a postprocessed identifier than to one that has to pass
through the preprocessor, when the magic gets used after
preprocessing.  When this is not the case, magic could be added to
NULL itself.

> As far as I recall, we weren't talking about magic in the first place.

We're talking about warning about certain uses of a certain
identifier and about certain uses of all other zeros.  Call it what
you like.

> | ...  Strictly conforming programs won't be
> | able to tell the difference.
>
> But a conforming compiler is required to diagnose ill-formed constructs
> (even if it accepts them).

This is an invisible (to programs, but not programmers) change to an
implementation, so it can't produce ill-formed constructs in programs.
Nor will it render the implementation unable to recognize ill-formed
constructs that it recognized before.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Dennett <james@evtechnology.com>
Date: Wed, 1 Nov 2000 17:07:01 GMT
Raw View
Christopher Eltschka wrote:
>
> Sebastian Moleski wrote:
> >
> > if ((const SomeClass *c = dynamic_cast<const SomeClass *>(o)) ==
> > __null_pointer_constant) {
> > }
>
> This would not be allowed since a declaration is not an expression.

True, given current rules.  Requiring a true boolean expression (rather than
just one which is convertible to bool) does mean that the scope of 'c' would
have to be extended with C++ as it stands.

> > I think the first one makes totally clear what is expected to happen without
> > the need for explicit comparison.
> >
> > Of course, this issue has been discussed to no end already and IMO there
> > really is no need to open it up again.
>
> There would be a simple solution: Extend the list of what conditions
> may be. Just as definitions have been allowed as well as expressions,
> a condition could be defined to be of boolean, integral or pointer
> type.
>
> But I think the worse conversion is the opposite: bool to int.
> IMHO it's not a big problem to either replace expr with
> (expr? 0 : 1) or to do an explicit cast of the expression to int.

I believe that there was some opposition on the committee to including an
implicit conversion from bool to int, but it clearly wasn't in the majority.
I guess because, as always, it would have broken too much existing (ugly IMO)
code.

There seems to be a breed of C/C++ programmer who thinks that it's in some
way natural to write

if (p)

to check if a pointer is null.  Granted, this is the most concise way to
write this in C/C++, and some would say that it's a false security to write
code such as

if (p == NULL)

as if C/C++ were relatively strongly typed.  Unfortunately, typing the
terser expression becomes a barrier to introducing better type safety.

As an aside, banning the implicit conversion to bool would eliminate the
old problem of accidentally typing 'if (p = NULL)' which has lead to the
disgusting but possible defensible practice of writing 'if (NULL == p)',
because the typo version would be illegal (unless we're working with
booleans anyway...)  That's one place where Java has better type safety
than C++.  (Don't flame; I'm not guilty of advocating Java as a decent
language!)

Maybe I'll hack gcc to disallow implicit conversions to bool (or at least
to warn about them) and see how I get along with using it.  Naturally I'd
leave a setting to allow backwards-compatible behaviour, as I guess I'll
need that in order to compile code written by other people.

-- James Dennett <jdennett@acm.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Wed, 1 Nov 2000 17:13:24 GMT
Raw View

Francis Glassborow wrote:
>
> In article <86r95acej1.fsf@gabi-soft.de>, kanze@gabi-soft.de writes
> >Well, the above is certainly the most frequent case.  Before void*, of
> >course, most C compilers allowed implicit conversions between all
> >pointer types, precisely so that the above would not need a cast.
>
> Not any C compiler that I ever used (or at least not in any mode that I
> would have used it) Implicit conversions of pointers is pure poison.
>

Yes it was, but that's the way C was in the late seventies.  You could even
do implicit conversion to and from int.  That and structure members were
global (not scoped to the individual structures)... ah the good ol' days :-)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Wed, 1 Nov 2000 19:10:38 GMT
Raw View
James Kuyper <kuyper@wizard.net> writes:

| kanze@gabi-soft.de wrote:
| >
| > Team-Rocket@gmx.net (Niklas Matthies) writes:
| ...
| > That, of course, argues for a special key word.  Which is probably the
| > best solution anyway.  But it requires a bit of effort -- if f is a
| > template function, what type should f(NULL) instantiate?
|
| That shouldn't be a difficult decision to make. It should be either
| void* or ambiguous,

Well, I have some trouble following the decisive argument which makes it
that void* should be selected.  The Standard says NULL is of integer type
(but doesn't mention which one).

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: Wed, 1 Nov 2000 19:13:10 GMT
Raw View
In article <39FDDB9A.B1B70576@sensor.com>,
  Ron Natalie <ron@sensor.com> wrote:

> kanze@gabi-soft.de wrote:

> > Most early Unix implementations did just that.  You could pass
> > NULL as the source to strcpy, and you would get an empty string.
> > I've talked to people who thought that this was guaranteed
> > behavior.

> No, the VAX did that.

So did a lot of others: the early Sun's and Apollo's, for example.
The first time I saw NULL passed to strcpy was in a program which had
been ported to about 20 different Unixes.  So it must have been pretty
common.

> The PDP-11 had p&P6 at location zero (it's
> the closest printable representation of the setd and following
> instructions in the crt0).

My experience was late enough that VAX was the standard machine,
rather than PDP:-).

> While, some idiots probably thought this was guaranteed, they were
> wrong in the early days as well.

I won't dispute that:-).  I remember having read that it was illegal
in K&R1.  Never the less, when we suppressed the feature, a lot of the
Unix utilities *didn't* run correctly.  (The Unix in question was
Xenix.  I don't think that the problem was due to Microsoft hacks, but
I can't be sure.)

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: Wed, 1 Nov 2000 19:13:22 GMT
Raw View
In article <39FF5F3E.3AC4DEA9@tribble.com>,
  David R Tribble <david@tribble.com> wrote:
> Gabriel Dos Reis wrote:
> >> Probably because adding a new keyword won't prohibit 0 to be
> >> interpreted as a null pointer constant? Or are you also proposing
> >> to prohibit 0 as a NPC?

> Ron Natalie <ron@sensor.com> writes:
> >| I am proposing both, for in my mind, it does no good to do one
> >| without the other.

> Gabriel Dos Reis wrote:
> > Actually, I was suspecting someone will propose that :-)  But
> > realistically we can't just ban 0 from being interpreted as a null
> > pointer constant.  Existing practices need to be supported; and I
> > don't think it is reasonable to require existing code to be modified
> > for this stuff.

> Existing code will already have to be changed to work with C99:

The question is: how much?

>     /* No headers included */

>     main()    // error, missing return type
>     {
>         printf("Hello, world\n");  // error, printf() undefined
>         return 0;
>     }

> This may or may not be as common as using 0 for null.

Well, your example isn't legal C89 -- printf requires a prototype.
Replace it with puts, however, and it's OK.

But you're basically right.  While I doubt anyone has written new C
for a while counting on implicit int and old-style functions, I
suspect that there is a large body of existing code which still uses
them.  And I suspect that most C compilers will continue to support
them, although maybe only with a special option.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: Wed, 1 Nov 2000 19:14:10 GMT
Raw View
In article <slrn8vu87v.46g.Team-Rocket@nightrunner.nm.dnsalias.net>,
Team-Rocket@gmx.net (Niklas Matthies) wrote:

>    [C99:6.3.2.3p3-5] ("Conversions"/"Other operands"/"Pointers")
>
>    An integer constant expression with the value 0, or such an
>    expression cast to type void *, is called a /null pointer constant/.
>    If a null pointer constant is converted to a pointer type, the
>    resulting pointer, called a /null pointer/, is guaranteed to compare
>    unequal to a pointer to any object or function.

I still only have the final draft text, which is different and does not
mention casting, only "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 any object of function".

If you have quoted exactly from the C9X standard, then the paragraph you
quoted doesn't make sense, because it does NOT say under which
circumstances a null pointer constant is converted to a pointer. cast !=
conversion. Either your quote is incorrect, or the C9X standard is broken.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: bonnard@clipper.ens.fr (Valentin Bonnard)
Date: Wed, 1 Nov 2000 19:17:27 GMT
Raw View
James Kuyper , dans son post <39FE33C8.BA90143@wizard.net> a    crit :
> Valentin Bonnard wrote:
> ...
>> To show a motivation for making (void*)0 a NPC in C. W/o this
>> rule, such code:
>>
>>   static int* p = (void*)0;
>>
>> wouldn't be valid C because the C compiler wants a constant
>> expression after the equal sign.
>
> According to C99, (void*)0 is an address constant, so that would still
> be valid C.

I still believe that it isn't valid C89, and that was my point -- I
was talking about a reason for making ((void*)0) a NPC.

--
Valentin Bonnard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Wed, 1 Nov 2000 19:18:53 GMT
Raw View

James.Kanze@dresdner-bank.com wrote:
>
>
> Are you sure?  I don't remember it in PCC around 86/87, but I could be
> mistaken.  And it *was* in "The C++ Programming Language", first
> edition.
>
PCC was certainly far from state of the art.  Void's showed up certainly
by the Version 7 PDP-11 compiler (and probably in the phototypesetter
compiler, but my memory is really hazy on that).  This was back around 1978!
I remeber chasing bugs in the implementation of voids certainly before 1981.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Wed, 1 Nov 2000 19:50:53 GMT
Raw View

James.Kanze@dresdner-bank.com wrote:
>

> So did a lot of others: the early Sun's and Apollo's, for example.
> The first time I saw NULL passed to strcpy was in a program which had
> been ported to about 20 different Unixes.  So it must have been pretty
> common.

I guess I am older than you and don't consider the SUN an early UNIX.
Apollo's (real Apollo's not the HP PA machines) didn't run UNIX.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: Wed, 1 Nov 2000 20:37:53 GMT
Raw View
On Wed,  1 Nov 2000 19:14:10 GMT, Christian Bau <christian.bau@isltd.insignia.com> wrote:
> In article <slrn8vu87v.46g.Team-Rocket@nightrunner.nm.dnsalias.net>,
> Team-Rocket@gmx.net (Niklas Matthies) wrote:
> >    [C99:6.3.2.3p3-5] ("Conversions"/"Other operands"/"Pointers")
> >
> >    An integer constant expression with the value 0, or such an
> >    expression cast to type void *, is called a /null pointer
> >    constant/. If a null pointer constant is converted to a pointer
> >    type, the resulting pointer, called a /null pointer/, is
> >    guaranteed to compare unequal to a pointer to any object or
> >    function.
>
> I still only have the final draft text, which is different and does
> not mention casting, only "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 any object of function".
>
> If you have quoted exactly from the C9X standard, then the paragraph
> you quoted doesn't make sense, because it does NOT say under which
> circumstances a null pointer constant is converted to a pointer. cast
> != conversion. Either your quote is incorrect, or the C9X standard is
> broken.

The quote is correct. It only specifies what happens if such a
conversion takes place, but it does not specify when it takes place.
This is specified at other places in the standard, where appropriate.
For example, special provisions are made for null pointer constants in
the clauses describing the assignement, comparison, and conditional
operators.

I understand there have been many significant changes since the last
public draft (which is not a "final" draft), so it is probably not wise
to use it as a reference for issues requiring such a level of detail as
the above.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Wed, 1 Nov 2000 21:34:49 GMT
Raw View
James.Kanze@dresdner-bank.com writes:

| In article <m33dheb1xr.fsf@merlin.codesourcery.com>,
|   Gabriel Dos Reis <gdr@merlin.codesourcery.com> wrote:
| > kanze@gabi-soft.de writes:
|
| > [...]
|
| > | I'm not sure, but isn't void a C++ innovation that was adopted by
| > | C?
|
| > Yes.  It was qualified as an "abomination" when used to designate a
| > nullary function (for example int main(void)), cf "D&E".
|
| *That* use of void is definitly an innovation of the C standards
| committee, and post-dates C++, since it is only relevant because of
| the introduction of C++ function prototypes in C.

That use of void was a C++ invention, later adopted by the C
committees.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Wed, 1 Nov 2000 21:56:55 GMT
Raw View
James Kuyper <kuyper@wizard.net> writes:

| Gabriel Dos Reis wrote:
| >
| > prj@po.cwru.edu (Paul Jarc) writes:
| ...
| > | Are const objects integral constant expressions in C++?
| > |   int const __null=0;
| > |   #define NULL __null
| > | Would this work?
| >
| > Yes.  But what is the difference with 0?
|
| Sometimes 0 is intended to be a NULL pointer, sometimes it's meant to be
| an integer. This suggestion would be to make it easy for an
| implementation to distinguish those two cases, and provide a warning
| when NULL is used in a context that calls for an integer, and also when
| any other form of 0 is used in a context that calls for a pointer.

How?  Special treatment, I presume.  But then, if the implementation is
going to do black magic, it doesn't need to define __null to be of
integer type at all.

I was under the impression that the above definition was intended to
replace 0 without any intervening magic.  But if we were to talk about
magic then actually, anything the implementation likes will work (as
far as it takes of care of observable behaviour) and the whole thread
is pointless.  For example

 #define NULL __null

would suffice and work.  Note there is no definition of __null (in C++
sense) (There is at least one implementation which handle NULL in that
special way). The implementation may not even have to define NULL as a
macro.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Wed, 1 Nov 2000 22:07:17 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| > Well, if the implementation can add more magic, why should it go the
| > trouble to define __null as above?
|
| The suggestion was based on the supposition that it's easier to add
| magic to a postprocessed identifier than to one that has to pass
| through the preprocessor, when the magic gets used after
| preprocessing.

Well, I should have missed that.

| ... When this is not the case, magic could be added to
| NULL itself.

100%, that was actually my point.

| > As far as I recall, we weren't talking about magic in the first place.
|
| We're talking about warning about certain uses of a certain
| identifier and about certain uses of all other zeros.  Call it what
| you like.

Well, that may be termed magic.  If we were to talk about magic, then
why don't think the implementation will put the magic in NULL itself
as an identifier?

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Wed, 1 Nov 2000 22:13:17 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> James Kuyper <kuyper@wizard.net> writes:
> | Sometimes 0 is intended to be a NULL pointer, sometimes it's meant to be
> | an integer. This suggestion would be to make it easy for an
> | implementation to distinguish those two cases, and provide a warning
> | when NULL is used in a context that calls for an integer, and also when
> | any other form of 0 is used in a context that calls for a pointer.
>
> How?  Special treatment, I presume.

Yes.

> But then, if the implementation is going to do black magic, it
> doesn't need to define __null to be of integer type at all.

True.  But in that case, __null must be magical for code generation as
well as for warnings.  My suggestion was intended to give as easy a
way as possible for implementations to find and warn about the problem
constructs.

> But if we were to talk about magic then actually, anything the
> implementation likes will work (as far as it takes of care of
> observable behaviour) and the whole thread is pointless.

It's no more pointless than any other instance of trying to find a
better way to do something that's already been done.

> The implementation may not even have to define NULL as a macro.

At least in C, it is required to be defined as a macro, and a strictly
conforming program can test that with '#if defined(NULL)'.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Wed, 1 Nov 2000 22:15:41 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> If we were to talk about magic, then why don't think the
> implementation will put the magic in NULL itself as an identifier?

It's still required to be a macro, so its definition is what must be
magical.  Perhaps the definition could itself be the token NULL, but
whatever it is, its magicality need not have any relation to its being
the definition of NULL.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Wed, 1 Nov 2000 23:22:36 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

[...]

| > But if we were to talk about magic then actually, anything the
| > implementation likes will work (as far as it takes of care of
| > observable behaviour) and the whole thread is pointless.
|
| It's no more pointless than any other instance of trying to find a
| better way to do something that's already been done.

It is pointless for comp.std.c++ and comp.std.c because it is more
related to a particular program translator internal details than to
C/C++ semantics: if I understand your objection correctly __null won't
be subjected to C/C++ semantics; so there is no point in discussing it
here.

| > The implementation may not even have to define NULL as a macro.
|
| At least in C, it is required to be defined as a macro, and a strictly
| conforming program can test that with '#if defined(NULL)'.

If the implementation is supposed to be doing black magic then why
should the above fail?

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Wed, 1 Nov 2000 23:22:52 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| > If we were to talk about magic, then why don't think the
| > implementation will put the magic in NULL itself as an identifier?
|
| It's still required to be a macro, so its definition is what must be
| magical.

The *observable behaviour* requires it to behave as if defined as a
macro.

| ...  Perhaps the definition could itself be the token NULL, but
| whatever it is, its magicality need not have any relation to its being
| the definition of NULL.

Now, you see why it is pointless (on comp.std.c++ and comp.std.c) to
discuss any definition of NULL to which we can't apply C/C++ semantics.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: Tue, 31 Oct 2000 16:46:52 GMT
Raw View
On Tue, 31 Oct 2000 14:32:07 GMT, James Kuyper <kuyper@wizard.net> wrote:
> "Balog Pal (mh)" wrote:
> > Paul Jarc wrote in message ...
> >=20
> > >I'm not one of them, but implementations are already free to do this=
:
> > >  enum { __null__ };
> > >  #define NULL __null__
[=B7=B7=B7]
> > >and then they can warn about using __null__ in a non-pointer context=
,
> >=20
> > And how that works out? I use a plenty of enums, all tend to just pla=
inly
> > convert to int silently. I'd guess that __null__ would do the same.
>=20
> Yes, but implementations are free to warn about anything. A conforming
[=B7=B7=B7]

Well, it also shouldn't be to hard for an implementation to internally
tag null pointer constants that come from expansions of the NULL macro
defined in the standard headers, and warn when it is used in an integer
context. Remember that the standard headers need not even exist as
actual files; the implementation only act as though they were. The only
case where this is not possible is when the preprocessor is a seperate
program. Most compilers nowadays have an integrated preprocessor, though,
therefore they could very well warn about misuses of NULL.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Tue, 31 Oct 2000 17:56:16 GMT
Raw View
Paul Jarc wrote:
...
> Are const objects integral constant expressions in C++?

Yes. 5.19p1: "An _integral constant-expression_ can involve ... const
variables ..."

>   int const __null=0;
>   #define NULL __null
> Would this work?

Yes.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 31 Oct 2000 18:02:22 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:
 >fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
 >> prj@po.cwru.edu (Paul Jarc) writes:
 >> >That's easily done by implementations:
 >> >    enum { __null=0 };
 >> >    #define NULL ((void*)__null) /* or just __null for C++ */
 >> >But removing the null pointer constant status of 0 and (void*)0 would
 >> >break existing code.
 >>
 >> In C++, enumeration constants like `__null' are not null pointer constants.
 >> The C++ standard says "A null pointer constant is an integral constant
 >> expression rvalue OF INTEGER TYPE that evaluates to zero." (4.10p1).
 >> In C++ enumeration constants have enumeration type, not integer type.
 >
 >Are const objects integral constant expressions in C++?

Yes, const objects can be integral constant expressions, so long as
they are initialized with constant expressions.  (See 5.19 [expr.const]
paragraph 1.)

 >  int const __null=0;
 >  #define NULL __null
 >Would this work?

Yes, that would work fine.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: Tue, 31 Oct 2000 18:05:48 GMT
Raw View
In article <slrn8vrk04.uu1.Team-Rocket@nightrunner.nm.dnsalias.net>,
Team-Rocket@gmx.net (Niklas Matthies) wrote:

> I meant the casting of integer expressions to some pointer type. Any
> integer may be converted to any pointer type [C99:6.3.2.3p5]. This is
> legal. It's just that the resulting pointer value, in the general case,
> is implementation-defined (also [C99:6.3.2.3p5]). Applying the cast
> operator with some pointer type as the target type on an integer
> expression performs such a conversion.
>
> The C standard then specifies, for the case that the integer expression
> is a null pointer constant, that the result shall be the null pointer
> value. I.e., it's a special case insofar as the C standard doesn't leave
> the choice to the implementation, for that case, but fixates the value
> of the result. But the cast as such is nevertheless your "normal"
> integer-to-pointer conversion.


Actually, that is not true. The C standard specifies a very small set of
circumstances (assignment, and comparison using == or !=, but not >=, <=
etc.) where a null pointer constant is converted to a null pointer of
appropriate type. Casting is not one of these circumstances.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Tue, 31 Oct 2000 18:19:26 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> prj@po.cwru.edu (Paul Jarc) writes:
> | Are const objects integral constant expressions in C++?
> |   int const __null=0;
> |   #define NULL __null
> | Would this work?
>
> Yes.  But what is the difference with 0?

The idea is for the implementation to complain when __null is used as
an integer.  You wouldn't want 0 to elicit that same complaint.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Tue, 31 Oct 2000 18:19:38 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> prj@po.cwru.edu (Paul Jarc) writes:
> | implementations are already free to do this:
> |   enum { __null__ };
> |   #define NULL __null__
>
> But then NULL is no longer of integer type.

The above works for C.  For C++, make __null__ be a const int with
value 0.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Marco Dalla Gasperina" <marcodg@panmed.com>
Date: Tue, 31 Oct 2000 18:37:54 GMT
Raw View
"Fergus Henderson" <fjh@cs.mu.OZ.AU> wrote in message
news:8tm9c3$dlr$1@mulga.cs.mu.OZ.AU...
> prj@po.cwru.edu (Paul Jarc) writes:
>  >  int const __null=0;
>  >  #define NULL __null
>  >Would this work?
>
> Yes, that would work fine.

That would allow:

const int* x = &NULL;

which is not valid if NULL is an rvalue.  That doesn't seem
right.

marco



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Tue, 31 Oct 2000 19:18:15 GMT
Raw View
fjh@cs.mu.OZ.AU (Fergus Henderson) writes:

[...]

|  >  int const __null=0;
|  >  #define NULL __null
|  >Would this work?
|
| Yes, that would work fine.

No, it isn't fine:  Now NULL is an lvalue.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Tue, 31 Oct 2000 19:21:51 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| > prj@po.cwru.edu (Paul Jarc) writes:
| > | implementations are already free to do this:
| > |   enum { __null__ };
| > |   #define NULL __null__
| >
| > But then NULL is no longer of integer type.
|
| The above works for C.  For C++, make __null__ be a const int with
| value 0.

But then __null__ with be an lvalue, contrary to what the C++ standard
requires.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Tue, 31 Oct 2000 19:22:56 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| > prj@po.cwru.edu (Paul Jarc) writes:
| > | Are const objects integral constant expressions in C++?
| > |   int const __null=0;
| > |   #define NULL __null
| > | Would this work?
| >
| > Yes.  But what is the difference with 0?
|
| The idea is for the implementation to complain when __null is used as
| an integer.  You wouldn't want 0 to elicit that same complaint.

Well, I think the most important issue, from a C++ point of view is a
type issue.  Any definition of NULL based on current C++ definition of
'null pointer constant' won't solve the fondamental problem and will
just be papering over the problem, (that is, fondamentally flawed).

What we need is a unique `null pointer constant type' with an
automatic conversion to a pointer type. Thanks to member templates,
one can reasonably approximate that.

Notice that g++ does something along those lines with a magic handling
of NULL (which is not necessarily defiined as const int __null = 0).

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: Tue, 31 Oct 2000 20:56:29 GMT
Raw View
On Tue, 31 Oct 2000 18:05:48 GMT, Christian Bau <christian.bau@isltd.insignia.com> wrote:
> In article <slrn8vrk04.uu1.Team-Rocket@nightrunner.nm.dnsalias.net>,
> Team-Rocket@gmx.net (Niklas Matthies) wrote:
>
> > I meant the casting of integer expressions to some pointer type. Any
> > integer may be converted to any pointer type [C99:6.3.2.3p5]. This is
> > legal. It's just that the resulting pointer value, in the general case,
> > is implementation-defined (also [C99:6.3.2.3p5]). Applying the cast
> > operator with some pointer type as the target type on an integer
> > expression performs such a conversion.
> >
> > The C standard then specifies, for the case that the integer expression
> > is a null pointer constant, that the result shall be the null pointer
> > value. I.e., it's a special case insofar as the C standard doesn't leave
> > the choice to the implementation, for that case, but fixates the value
> > of the result. But the cast as such is nevertheless your "normal"
> > integer-to-pointer conversion.
>
> Actually, that is not true. The C standard specifies a very small set of
> circumstances (assignment, and comparison using == or !=, but not >=, <=
> etc.) where a null pointer constant is converted to a null pointer of
> appropriate type. Casting is not one of these circumstances.

Yes it is:

   [C99:6.5.4p4] ("Cast operator")

   Preceding an expression by a parenthesized type name converts the
   value of the expression to the named type. This construction is
   called a /cast/. A cast that specifies no conversion has no effect on
   the type or value of an expression.

   [C99:6.3.2.3p3-5] ("Conversions"/"Other operands"/"Pointers")

   An integer constant expression with the value 0, or such an
   expression cast to type void *, is called a /null pointer constant/.
   If a null pointer constant is converted to a pointer type, the
   resulting pointer, called a /null pointer/, is guaranteed to compare
   unequal to a pointer to any object or function.

   Conversion of a null pointer to another pointer type yields a null
   pointer of that type. Any two null pointers shall compare equal.

   An integer may be converted to any pointer type. Except as previously
   specified, the result is implementation-defined, might not be
   correctly aligned, might not point to an entity of the referenced
   type, and might be a trap representation.

A cast with pointer type applied to an expression of integer type
converts the value of that expression type to the named pointer type
(6.5.4.p4). In general, the resulting pointer value is implementation-
defined (6.3.2.3p5). But in the case that the integer expression was a
constant integer expression with value 0, the resulting pointer value is
a null pointer (6.3.2.3p3) (of the named type).

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: Wed, 1 Nov 2000 01:07:03 GMT
Raw View
Sebastian Moleski wrote:
>
> "James Dennett" <james@evtechnology.com>:
> | michael wrote:
> ...
> | I sometimes wish that there were two modes defined by Standard C++ --
> backwards (C-compatible) mode, and sensible (safe) mode.  I dread to think
> how much compexity this would have added to the standardization process
> though.  It would be nice to deprecate
> | implicit conversions to bool at some time in the future, and I'd be for
> redefining "null pointer constant" at that time to mean something like
> "__null_pointer_constant", which would be a new reserved word.  Probably
> more experienced people can think of
> | better ways to get rid of this overloading of 0.
>
> If I was to decide, you had my vote against it. I sometimes write code like
> the following where an explicit comparison with 0 would be just plain ugly:
>
> // current way
> if (const SomeClass *c = dynamic_cast<const SomeClass *>(o)) {
> }
>
> // your way
> if ((const SomeClass *c = dynamic_cast<const SomeClass *>(o)) ==
> __null_pointer_constant) {
> }

This would not be allowed since a declaration is not an expression.

>
> I think the first one makes totally clear what is expected to happen without
> the need for explicit comparison.
>
> Of course, this issue has been discussed to no end already and IMO there
> really is no need to open it up again.

There would be a simple solution: Extend the list of what conditions
may be. Just as definitions have been allowed as well as expressions,
a condition could be defined to be of boolean, integral or pointer
type.

But I think the worse conversion is the opposite: bool to int.
IMHO it's not a big problem to either replace expr with
(expr? 0 : 1) or to do an explicit cast of the expression to 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: Wed, 1 Nov 2000 01:07:16 GMT
Raw View
Sebastian Moleski wrote:
>
> We have eliminated any references to NULL in our own code. IMO, it's not
> right to use a non-keyword to express something as special as a null-pointer
> constant.

Why does it matter to you if it's a keyword? Unless you
are using it in the preprocessor, there's absolutely no
difference between a macro and a keyword with the same
behaviour. Indeed, if tomorrow NULL started to be a keyword,
but still behaved as null pointer constant (including having
type int), the only way you could notice it would be by using
the preprocessor. And of course, a macro being defined to
a keyword behaves exactly like that keyword.

Another example: dynamic_cast is a keyword. But what would be
different, if it was just a built-in global template function
which does the magic? Well, you could hide the name by declaring
f.ex. a variable with that name, and you could take it's address.
But that's about it. (Note that "built-in" means you don't have
to include a header - the compiler knows it's definition).

[...]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Wed, 1 Nov 2000 01:07:26 GMT
Raw View
"Marco Dalla Gasperina" <marcodg@panmed.com> writes:
> > prj@po.cwru.edu (Paul Jarc) writes:
> >  >  int const __null=0;
> >  >  #define NULL __null
>
> That would allow:
>
> const int* x = &NULL;
>
> which is not valid if NULL is an rvalue.  That doesn't seem
> right.

But this would be a non-pointer-context use of NULL, so you'd get a
warning.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Wed, 1 Nov 2000 01:07:37 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
> fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
> |  >  int const __null=0;
> |  >  #define NULL __null
> |  >Would this work?
> |
> | Yes, that would work fine.
>
> No, it isn't fine:  Now NULL is an lvalue.

The implementation knows it's an lvalue, but it need not reveal that
to programs.  Add more magic.  Strictly conforming programs won't be
able to tell the difference.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Wed, 1 Nov 2000 01:09:47 GMT
Raw View
David R Tribble <david@tribble.com> writes:
>| The addition of a new keyword or special identifier (e.g., 'null',
>| '__null__', or simply 'NULL') for both C and C++ has been suggested
>| several times in the past.  But no one seems convinced or moved
>| enough to actually get this into the language.  (C++ needs it far
>| more than C.)

Gabriel Dos Reis wrote:
> Probably because adding a new keyword won't prohibit 0 to be
> interpreted as a null pointer constant? Or are you also proposing to
> prohibit 0 as a NPC?

I can always hope.  Take one step in that direction at a time: first,
add a real 'null' constant to the language(s); then, probably years
later, mandate that 0 is only and always an integer.

However, by then I probably will have abandoned C and C++ for the
more type-safe pastures of Java III.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Wed, 1 Nov 2000 01:09:54 GMT
Raw View
fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
>>  That is fine and good.  But why did he decide to make `(void *)0'
>>  not be a null pointer constant?  It can't have been for reasons
>>  of type safety, since allowing `(void *)0' as a null pointer
>>  constant would make things more type-safe, not less type-safe.

kanze@gabi-soft.de wrote:
> I'm just guessing, but I'd guess that it was because at the time
> "(void*)0" wasn't a null pointer constant in C either, at least on the
> machines Stroustrup was using.  K&R 1 don't mention the possibility.
> (Rather understandably, since the language they are defining doesn't
> have void.)

That maybe explains why Stroustrup didn't allow a special case for
'((void*)0)', but it doesn't explain why the ISO C++ committee didn't
consider it (many years later).

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Wed, 1 Nov 2000 01:10:02 GMT
Raw View
Gabriel Dos Reis wrote:
>> Probably because adding a new keyword won't prohibit 0 to be
>> interpreted as a null pointer constant? Or are you also proposing to
>> prohibit 0 as a NPC?

Ron Natalie <ron@sensor.com> writes:
>| I am proposing both, for in my mind, it does no good to do one
>| without the other.

Gabriel Dos Reis wrote:
> Actually, I was suspecting someone will propose that :-)  But
> realistically we can't just ban 0 from being interpreted as a null
> pointer constant.  Existing practices need to be supported; and I
> don't think it is reasonable to require existing code to be modified
> for this stuff.

Existing code will already have to be changed to work with C99:

    /* No headers included */

    main()    // error, missing return type
    {
        printf("Hello, world\n");  // error, printf() undefined
        return 0;
    }

This may or may not be as common as using 0 for null.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: Wed, 1 Nov 2000 01:10:10 GMT
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:

>fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
>
>[...]
>
>|  >  int const __null=0;
>|  >  #define NULL __null
>|  >Would this work?
>|
>| Yes, that would work fine.
>
>No, it isn't fine:  Now NULL is an lvalue.

Oh, good point.  But easily remedied.
For example, the following

 int const __null = 0;
 #define NULL (+__null)

would be a valid definition of NULL.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Wed, 1 Nov 2000 15:46:19 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:
| > fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
| > |  >  int const __null=0;
| > |  >  #define NULL __null
| > |  >Would this work?
| > |
| > | Yes, that would work fine.
| >
| > No, it isn't fine:  Now NULL is an lvalue.
|
| The implementation knows it's an lvalue, but it need not reveal that
| to programs.  Add more magic.

Well, if the implementation can add more magic, why should it go the
trouble to define __null as above?

As far as I recall, we weren't talking about magic in the first place.
Should we invoke black magic, there is no point in discussing the
matter at all.

| ...  Strictly conforming programs won't be
| able to tell the difference.

But a conforming compiler is required to diagnose ill-formed constructs
(even if it accepts them).

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Wed, 1 Nov 2000 16:43:32 GMT
Raw View
Gabriel Dos Reis wrote:
>
> prj@po.cwru.edu (Paul Jarc) writes:
...
> | Are const objects integral constant expressions in C++?
> |   int const __null=0;
> |   #define NULL __null
> | Would this work?
>
> Yes.  But what is the difference with 0?

Sometimes 0 is intended to be a NULL pointer, sometimes it's meant to be
an integer. This suggestion would be to make it easy for an
implementation to distinguish those two cases, and provide a warning
when NULL is used in a context that calls for an integer, and also when
any other form of 0 is used in a context that calls for a pointer.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Wed, 1 Nov 2000 16:43:34 GMT
Raw View
Niklas Matthies wrote:
>=20
> On Tue, 31 Oct 2000 14:32:07 GMT, James Kuyper <kuyper@wizard.net> wrot=
e:
> > "Balog Pal (mh)" wrote:
> > > Paul Jarc wrote in message ...
> > >
> > > >I'm not one of them, but implementations are already free to do th=
is:
> > > >  enum { __null__ };
> > > >  #define NULL __null__
> [=B7=B7=B7]
> > > >and then they can warn about using __null__ in a non-pointer conte=
xt,
> > >
> > > And how that works out? I use a plenty of enums, all tend to just p=
lainly
> > > convert to int silently. I'd guess that __null__ would do the same.
> >
> > Yes, but implementations are free to warn about anything. A conformin=
g
> [=B7=B7=B7]
>=20
> Well, it also shouldn't be to hard for an implementation to internally
> tag null pointer constants that come from expansions of the NULL macro

Yes, and that's exactly the purpose of this suggestion: __null__ is the
tag.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 30 Oct 2000 20:28:36 GMT
Raw View

David R Tribble wrote:
>
>
>
> 1. NULL could be #defined as '((void*)0)' in both C and C++.
>
> 2. The uses of NULL (or '((void*)0)') would be more type-safe than
>  '0' in both C and C++.

You have no real type safety unless 0 is disallowed.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 30 Oct 2000 20:31:41 GMT
Raw View

kanze@gabi-soft.de wrote:
>
> I'm not sure, but isn't void a C++ innovation that was adopted by C?

Nope, might have been some cross fertilization, but void showed up in C before
C with classes existed.
>
> I'd also bet that the definition of a null pointer constant in the ARM
> was written before (void*)0 was a legal null pointer constant in C.  Or
> simply copied from text that was written before.
>
The C89 spec predates the ARM by a year.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 30 Oct 2000 20:35:29 GMT
Raw View

Gabriel Dos Reis wrote:
>
>
> Probably because adding a new keyword won't prohibit 0 to be
> interpreted as a null pointer constant? Or are you also proposing to
> prohibit 0 as a NPC?
>

I am proposing both, for in my mind, it does no good to do one without
the other.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Mon, 30 Oct 2000 20:51:15 GMT
Raw View
kanze@gabi-soft.de writes:

[...]

| I'm not sure, but isn't void a C++ innovation that was adopted by C?

Yes.  It was qualified as an "abomination" when used to designate a
nullary function (for example int main(void)), cf "D&E".

| I'd also bet that the definition of a null pointer constant in the ARM
| was written before (void*)0 was a legal null pointer constant in C.  Or
| simply copied from text that was written before.

Well, actually Bjarne (and M. Ellis) discussed explicitly the
"void*" stuff in ARM (page 36) and refered to C as "ANSI C".

I have to confess that my copy of ARM is the 19th printing of December
1997.  I don't know if there is any substantial difference in that
area, compared to the original printing.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 30 Oct 2000 20:51:46 GMT
Raw View

kanze@gabi-soft.de wrote:

>
> Most early Unix implementations did just that.  You could pass NULL as
> the source to strcpy, and you would get an empty string.  I've talked to
> people who thought that this was guaranteed behavior.
>

No, the VAX did that.  The PDP-11 had p&P6 at location zero (it's the closest
printable representation of the setd and following instructions in the crt0).

While, some idiots probably thought this was guaranteed, they were wrong in
the early days as well.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Mon, 30 Oct 2000 21:25:43 GMT
Raw View
Ron Natalie <ron@sensor.com> writes:

| Gabriel Dos Reis wrote:
| >
| >
| > Probably because adding a new keyword won't prohibit 0 to be
| > interpreted as a null pointer constant? Or are you also proposing to
| > prohibit 0 as a NPC?
| >
|
| I am proposing both, for in my mind, it does no good to do one without
| the other.

Actually, I was suspecting someone will propose that :-)  But
realistically we can't just ban 0 from being interpreted as a null
pointer constant.  Existing practices need to be supported; and I
don't think it is reasonable to require existing code to be modified
for this stuff.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Mon, 30 Oct 2000 21:42:34 GMT
Raw View
kanze@gabi-soft.de writes:
> Realistically, there will never be a time when 0 will not convert
> implicitly to a null pointer.

But implementations are free to warn about it.  A compiler could even
exit nonzero to cause a build script to fail, as long as the
implementation documented that such an exit does not necessarily
constitute rejection.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Mon, 30 Oct 2000 21:49:07 GMT
Raw View
fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
> prj@po.cwru.edu (Paul Jarc) writes:
> >That's easily done by implementations:
> >    enum { __null=0 };
> >    #define NULL ((void*)__null) /* or just __null for C++ */
> >But removing the null pointer constant status of 0 and (void*)0 would
> >break existing code.
>
> In C++, enumeration constants like `__null' are not null pointer constants.
> The C++ standard says "A null pointer constant is an integral constant
> expression rvalue OF INTEGER TYPE that evaluates to zero." (4.10p1).
> In C++ enumeration constants have enumeration type, not integer type.

Are const objects integral constant expressions in C++?
  int const __null=0;
  #define NULL __null
Would this work?


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: Mon, 30 Oct 2000 22:21:00 GMT
Raw View
On Mon, 30 Oct 2000 18:41:45 GMT, kanze@gabi-soft.de <kanze@gabi-soft.de>=
 wrote:
> Team-Rocket@gmx.net (Niklas Matthies) writes:
> |>  On Sun, 15 Oct 2000 03:38:14 GMT, kanze@gabi-soft.de <kanze@gabi-so=
ft.de> wrote:
> |>  > wmm@fastdial.net writes:
> |>  [=B7=B7=B7]
> |>  > |>  1) The acceptance of "(void*)0" as a null pointer constant
> |>  > |>  is consistent with, not an exception to, C's rules for
> |>  > |>  pointer compatibility.
>=20
> |>  > No, because C's rules don't have anything to do with pointer
> |>  > compatibility.  A null pointer is a special case, and although
> |>  > (void*)0 may look like casting an integral 0 to void*, it is *not=
*
> |>  > a normal cast -- the special properties of a null pointer must be
> |>  > respected.
>=20
> |>  It is in fact a "normal cast".
>=20
> How do you define a "normal cast".  It has the syntax of a normal cast,
> but it certainly doesn't have the semantics.

I meant the casting of integer expressions to some pointer type. Any
integer may be converted to any pointer type [C99:6.3.2.3p5]. This is
legal. It's just that the resulting pointer value, in the general case,
is implementation-defined (also [C99:6.3.2.3p5]). Applying the cast
operator with some pointer type as the target type on an integer
expression performs such a conversion.

The C standard then specifies, for the case that the integer expression
is a null pointer constant, that the result shall be the null pointer
value. I.e., it's a special case insofar as the C standard doesn't leave
the choice to the implementation, for that case, but fixates the value
of the result. But the cast as such is nevertheless your "normal"
integer-to-pointer conversion.

As an anology, when converting unsigned integer values to signed integer
types, the result is implementation-defined when the unsigned value is
not representable by the signed integer type, but is specified by the
standard if the value can be represented by the signed integer type.
But neither, when performed through application of a cast operator (what
we informally call "casting" or "a cast"), are somehow "special". The
standard just happens to define the result for certain values, and lets
the implementation decide for the others.

> |>  Furthermore, because of [C99:6.3.2.3p3s2-p4]
>=20
> |>     If a null pointer constant is converted to a pointer type, the
> |>     resulting pointer, called a null pointer, is guaranteed to
> |>     compare unequal to a pointer to any object or function.
>=20
> |>     Conversion of a null pointer to another pointer type yields a
> |>     null pointer of that type. Any two null pointers shall compare
> |>     equal.
>=20
> |>  the expression `(void *) 0' is not only a null pointer constant, bu=
t
> |>  at the same time a null pointer (because it's the null pointer
> |>  constant `0' converted to a pointer type), which `0' by itself is
> |>  not.
>=20
> Ahah.  I see what you mean.  "(void*)0" is both --null pointer
> constant--, and (void*)--null pointer constant--.  So the cast is both
> a normal cast *and* one with special semantics.

Not really. It's a "normal" cast to begin with; see above.

My point here was that although `(void *) 0' is a null pointer constant,
it is not a null pointer (value) by virtue of this fact, but by the fact
that `0' is also a null pointer constant, and converting `0' to a
pointer type yields a null pointer (value). Hence, in the expression

      (char *) (void *) 0
              ^        ^
              B        A

it is not clear whether the transition from null pointer constant to
null pointer (value) happens at A or at B (both are specified by the
standard). Fortunately, the outcome is the same, so it doesn't matter.
But I think that it is not totally cosher from a formal point of view.

> |>  The only effect of `(void *) 0' being a null pointer constant in C
> |>  (unless I overlooked something) is
> |>  (1) that it is allowed to be the expansion of the NULL macro and
> |>  (2) that an expression like
>=20
> |>     ( expr ? (void *) 0 : (char *) something )
>=20
> |>  has type `char *' and not type `void *', because there is a special
> |>  case made for null pointer constants as second or third operand to
> |>  the ?: operator.
>=20
> Doesn't this special case also affect void* in C?  (I'm asking; I reall=
y
> don't know.  But given the implicit conversion of void* in C, it would
> make sense.)

I was talking about C here to begin with. Or else I don't understand
what you're getting at. :)

> |>  > The reason it [void * 0] does work in C is because the standard
> |>  > says it works.
>=20
> |>  Not quite. If the C standard didn't make `(void *) 0' a null pointe=
r
> |>  constant, the only real difference would be for the ?: operator, as
> |>  explained above. In all other cases where the C standard makes
> |>  specific provisions for null pointer constants, a constant
> |>  expression with type void * (which `(void *) <any integer constant
> |>  expression>' is) would behave the same.
>=20
> So I believe.  Never the less, they *did* make it a null pointer
> constant.  And it must have been a conscious decision, since it wasn't
> the case before standardization.

I believe the reason was that they wanted NULL to expand to a null
pointer constant, and at the same time wanted to allow NULL to expand to
the commonly used `(void *) 0'. So they had to make `(void *) 0' a null
pointer constant.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 30 Oct 2000 22:24:15 GMT
Raw View

Ron Natalie wrote:
>

>
> So was if(p == -1), Doug.  Early C++ pretty much interchanged
> ints and pointers indescrimately.  The original C reference
> manual doesn't mention null pointers anywehre.

That should say Early "C" not "C++"

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Mon, 30 Oct 2000 22:25:03 GMT
Raw View
"Balog Pal" <pasa@lib.hu> writes:
> "David R Tribble" <david@tribble.com> wrote
> > The addition of a new keyword or special identifier (e.g., 'null',
> > '__null__', or simply 'NULL') for both C and C++ has been suggested
> > several times in the past.  But no one seems convinced or moved enough
> > to actually get this into the language.  (C++ needs it far more than
> > C.)
>
> I'd definitely vote in favour.
>
> I think some of the actual voters are present her, thet could enlighten why
> such a specialised npc would be bad.

I'm not one of them, but implementations are already free to do this:
  enum { __null__ };
  #define NULL __null__
and then they can warn about using __null__ in a non-pointer context,
and about using other zero expressions in a pointer context.
Requiring such a __null__ would not be very useful unless other zeros
were prohibited as null pointer constants, and there's simply too much
code that depends on that feature to remove it.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: prj@po.cwru.edu (Paul Jarc)
Date: Mon, 30 Oct 2000 22:25:27 GMT
Raw View
Ron Natalie <ron@sensor.com> writes:
> I was looking for something that was NOT optional on the implementations
> default.  A type that the compiler is required to issue a diagnostic
> for, not one that it might.

You can't get there from here.  This change will never be made to C or
C++; there's just too much code depending on 0 being a null pointer
constant.  The half-solution I gave is sufficient to catch all the
misuses of 0 or NULL, and it's the best you can hope for, short of
creating a new language.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Balog Pal (mh)" <pasa@lib.hu>
Date: Tue, 31 Oct 2000 00:55:41 GMT
Raw View
Paul Jarc wrote in message ...

>I'm not one of them, but implementations are already free to do this:
>  enum { __null__ };
>  #define NULL __null__


Is it allowed to redefine NULL at all?

>and then they can warn about using __null__ in a non-pointer context,


And how that works out? I use a plenty of enums, all tend to just plainly
convert to int silently. I'd guess that __null__ would do the same.

>and about using other zero expressions in a pointer context.
>Requiring such a __null__ would not be very useful unless other zeros
>were prohibited as null pointer constants, and there's simply too much
>code that depends on that feature to remove it.


No one told that should be done tomorrow. But as a first step start with a
specialised thing, then decrepate plain 0 then maybe 10 years from now stop
it altogether.

Paul



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: joerg.barfurth@attglobal.net (Joerg Barfurth)
Date: Tue, 31 Oct 2000 01:46:46 GMT
Raw View
<kanze@gabi-soft.de> wrote:

> joerg.barfurth@attglobal.net (Joerg Barfurth) writes:

> |>  So the following (which elides the issue of what C++ allows for NUL=
L)
>=20
> |>     #define NOTHING ((void*)0)
> |>     static int *p =3D NOTHING;
>=20
> |>  - is legal C (at least) since C90

> |>  - weren't legal C, if only "integer constant expressions with the
> |>    value 0" were allowed as null pointer constants=20
> |>    (as is the case in C++)
>=20
> It would still be legal C.  The exact analysis would be different, but =
0
> is a null pointer constant, so casting it to a pointer type will result
> in a null pointer (of a specific type).  And void* converts implicitly
> to all pointer types (in C).

I'm not a C expert, so correct me if I'm wrong.

The issue in the above was exactly that it were illegal although in C
(as opposed to C++) a void* converts implicitly to any pointer type.

The idea was that in C90=20

  #define NOTHING ((void*)(char*)0)
  static int* p =3D NOTHING;

isn't legal, but only because this isn't a legal 'constant expression',
which is required for initializing a static variable. The expression is
of suitable type, and it is constant for many purposes (e.g. it always
evaluates to a null pointer value), but it isn't within the definition
C90 gives for constant expressions.

The same would hold for ((void*)0), so dropping it from the list of
special cases for null pointer constants would have had quite some
effect even in C90.

IIRC it has been put forward since, that this has changed in C99.

Rgds. J=F6rg

--=20
J=F6rg Barfurth                         joerg.barfurth@attglobal.net
-------------- using std::disclaimer; -----------------------------
Download:     StarOffice 5.2 at       http://www.sun.com/staroffice
Participate:  OpenOffice now at       http://www.OpenOffice.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Tue, 31 Oct 2000 02:25:15 GMT
Raw View
Ron Natalie wrote:
>
> David R Tribble wrote:
> >
> >
> >
> > 1. NULL could be #defined as '((void*)0)' in both C and C++.
> >
> > 2. The uses of NULL (or '((void*)0)') would be more type-safe than
> >  '0' in both C and C++.
>
> You have no real type safety unless 0 is disallowed.

There would be real type safety on every implementation that took
advantage of that option, in every place where NULL is used. The fact
that there's no type safety on other implementations or in other pieces
of code doesn't negate the places and platforms where it does help.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Tue, 31 Oct 2000 14:32:16 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| fjh@cs.mu.OZ.AU (Fergus Henderson) writes:
| > prj@po.cwru.edu (Paul Jarc) writes:
| > >That's easily done by implementations:
| > >    enum { __null=0 };
| > >    #define NULL ((void*)__null) /* or just __null for C++ */
| > >But removing the null pointer constant status of 0 and (void*)0 would
| > >break existing code.
| >
| > In C++, enumeration constants like `__null' are not null pointer constants.
| > The C++ standard says "A null pointer constant is an integral constant
| > expression rvalue OF INTEGER TYPE that evaluates to zero." (4.10p1).
| > In C++ enumeration constants have enumeration type, not integer type.
|
| Are const objects integral constant expressions in C++?
|   int const __null=0;
|   #define NULL __null
| Would this work?

Yes.  But what is the difference with 0?

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Tue, 31 Oct 2000 14:32:07 GMT
Raw View
"Balog Pal (mh)" wrote:
>
> Paul Jarc wrote in message ...
>
> >I'm not one of them, but implementations are already free to do this:
> >  enum { __null__ };
> >  #define NULL __null__
>
> Is it allowed to redefine NULL at all?

Who said anything about redefining it? This is being proposed for the
initial definition - the one that must be placed by the implementation
in several standard headers: <cstddef>, <cstring>, <ctime>, <cwchar>,
<clocale>, <cstdio>, and the corresponding <name.h> C headers.

> >and then they can warn about using __null__ in a non-pointer context,
>
> And how that works out? I use a plenty of enums, all tend to just plainly
> convert to int silently. I'd guess that __null__ would do the same.

Yes, but implementations are free to warn about anything. A conforming
implementation could give a warning about the fact that you're compiling
your code on Friday the 13th. It's certainly free to complain about use
of __null__ in a context that requires an integer. It must not refuse to
translate code for that reason, but it can warn about it.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Tue, 31 Oct 2000 16:45:51 GMT
Raw View
Valentin Bonnard wrote:
...
> To show a motivation for making (void*)0 a NPC in C. W/o this
> rule, such code:
>
>   static int* p = (void*)0;
>
> wouldn't be valid C because the C compiler wants a constant
> expression after the equal sign.

According to C99, (void*)0 is an address constant, so that would still
be valid C.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Tue, 31 Oct 2000 16:45:59 GMT
Raw View
David Thompson wrote:
>=20
> <kanze@gabi-soft.de> wrote :
> ....
> > You're thinking of C (where there are no rvalues).  In C++, an
> > expression is either an lvalue or an rvalue, and there is an lvalue t=
o
> > rvalue conversion (implicit, of course).
> >
> C certainly does have rvalues and lvalues the same as C++,
> with an implicit conversion:  C89 6.2.2.1; C99 6.3.2.1p2,3.
> C does not have _user-defined_ conversions.

You're right about the conversions, of course. However, the only
statement in the entire C99 standard that mentions "rvalue" is
non-normative text in footnote 53 that makes it clear that "rvalue" is
not the term used by C99 for that concept: "What is sometimes called
=91=91rvalue=92=92 is in this International Standard described as the =91=
=91value of
an expression=92=92."

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Tue, 31 Oct 2000 16:46:05 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

| "Balog Pal" <pasa@lib.hu> writes:
| > "David R Tribble" <david@tribble.com> wrote
| > > The addition of a new keyword or special identifier (e.g., 'null',
| > > '__null__', or simply 'NULL') for both C and C++ has been suggested
| > > several times in the past.  But no one seems convinced or moved enough
| > > to actually get this into the language.  (C++ needs it far more than
| > > C.)
| >
| > I'd definitely vote in favour.
| >
| > I think some of the actual voters are present her, thet could enlighten why
| > such a specialised npc would be bad.
|
| I'm not one of them, but implementations are already free to do this:
|   enum { __null__ };
|   #define NULL __null__

But then NULL is no longer of integer type.

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 30 Oct 2000 18:25:38 GMT
Raw View

Paul Jarc wrote:
>
> Ron Natalie <ron@sensor.com> writes:
> > Paul Jarc wrote:
> > >     enum { __null=0 };
> >
> > NOPE, that's no better than before __null as an enum identifier is still
> > implicitly convertable to INT.
>
> So the implementation must still translate the program, but it can
> issue a warning whenever this identifier is used in a non-pointer
> context, which is all you need when you're worried about misusing it
> by accident.  Remember that silence is never required.

I was looking for something that was NOT optional on the implementations
default.  A type that the compiler is required to issue a diagnostic
for, not one that it might.
>
> > The fact that zero made a good invalid pointer value is purely
> > historical.
>
> Even more than you think - the historical nature of the statement
> doesn't support your case any more than the statement itself supports
> the case of keeping 0 as a null pointer constant.  A null pointer
> represented in source code as '0' need not be represented at runtime
> as all-bits-zero.  These days, aside from backward compatibility, 0 is
> used just for its mnemonic value for a pointer that points to nothing.
> It doesn't tell you anything about the bits.
>
Nope, you missed the point.  The origin of zero predates the concept of
a null pointer (or null pointer coinstant) in C.  The original C has
no such entity.  There were two prevailing values used to signal bad
pointers: 0 and -1 (or all ones if you will). The UNIX kernel itself
up until Version 7 (about 1979) used a pointer value of -1 to indicate
the end of the argv array.  These vealues were used because IT WAS
POSSIBLE to directly convert these integer values into the same
valued pointer.

The whole concept of zero as the null pointer concept and the fact that
it might have to be converted to some machine representable value other
than zero was a stab at legitimiizing existing [in my opinion bad]
progamming practice.  A non-integer representation should have been
chosen.

Frankly, NULL is problematic.  It's a later concept (showed up in the
stdio header where it demostrates the general hosed up nature of
that piece of junk where NULL, EOF, and 0 are used indescriminately).
If you're not going to use something other than zero for it, what's the
point of not using zero.  The whole cast on NULL kludge was an attempt
to get around the "indeterminate arg" calling sequence in C.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Mon, 30 Oct 2000 18:32:23 GMT
Raw View
James Dennett <jdennett@acm.org> writes:

|>  kanze@gabi-soft.de wrote:

|>  > wmm@fastdial.net writes:

|>  > |>  2) The reason "(void*)0" _doesn't_ work in C++ is a direct
|>  > |>  consequence of the difference between the pointer compatibility
|>  > |>  rules of C and C++.

|>  > The reason (void*)0 doesn't work in C++ is because the standard
|>  > says it doesn't work.  The reason it does work in C is because the
|>  > standard says it works.

|>  Here I confess to being mystified.

|>  Suppose C didn't say that (void *)0 was a NPC.  Wouldn't it still be
|>  legal (in C) to write

|>  struct X *p =3D (void *)0;

Yes, but the meaning would be slightly different.

|>  simply because 0 is a NPC, so (void *)0 is a null pointer, and
|>  (void*) converts (in C) to (X*)?

0 is, first and foremost, an int.  So (void*)0, would not be a null
pointer constant, just as it isn't a null pointer constant in C++.  I'm
not sure that one could actually find a program in C where this would
make a difference.

|>  If the above code would be legal C, why make
|>  the dispensation for (void *)0 -- is this just to ensure that the
|>  following code is non-portable?

There is no special dispensation needed, in either case.  A null pointer
constant converts implicitly to a null pointer of the appropriate type.
Regardless of how we decide that a null pointer constant should be
spelled.

|>  int i =3D NULL;

|>  Ugly code for sure, but it would also be ugly to say that its
|>  legality is implementation-defined.  I'd prefer it to be outright
|>  illegal (maybe in the next revision of the C++ Standard?  Please?!)
|>  but if that can't be so then at least C++ defined it consistently
|>  across all compilers which conform in this respect.

The situation is, I agree, far from ideal.  For example:
    extern void f(void*) ;
    extern void f(long) ;
It's currently implementation defined whether f(NULL) is ambiguous or
not.  The current definition already isn't consistent across all
compilers.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Mon, 30 Oct 2000 18:32:37 GMT
Raw View
fjh@cs.mu.OZ.AU (Fergus Henderson) writes:

|>  That is fine and good.  But why did he decide to make `(void *)0'
|>  not be a null pointer constant?  It can't have been for reasons
|>  of type safety, since allowing `(void *)0' as a null pointer constant
|>  would make things more type-safe, not less type-safe.

I'm just guessing, but I'd guess that it was because at the time
"(void*)0" wasn't a null pointer constant in C either, at least on the
machines Stroustrup was using.  K&R 1 don't mention the possibility.
(Rather understandably, since the language they are defining doesn't
have void.)

I'm not sure, but isn't void a C++ innovation that was adopted by C?

I'd also bet that the definition of a null pointer constant in the ARM
was written before (void*)0 was a legal null pointer constant in C.  Or
simply copied from text that was written before.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Mon, 30 Oct 2000 18:33:36 GMT
Raw View
joerg.barfurth@attglobal.net (Joerg Barfurth) writes:

|>  Niklas Matthies <Team-Rocket@gmx.net> wrote:

|>  So the following (which elides the issue of what C++ allows for NULL)=
=20

|>     #define NOTHING ((void*)0)
|>     static int *p =3D NOTHING;

|>  - is legal C (at least) since C90

Which was before the C definition was established.  (Seriously, it has
been legal C ever since C adopted the void type.  But I think that this
was after the original C++, and that in fact, void originated in C++.)

|>  - weren't legal C, if only "integer constant expressions with the
|>    value 0" were allowed as null pointer constants=20
|>    (as is the case in C++)

It would still be legal C.  The exact analysis would be different, but 0
is a null pointer constant, so casting it to a pointer type will result
in a null pointer (of a specific type).  And void* converts implicitly
to all pointer types (in C).

|>  - is not legal C++ (but for different reasons)

It's not legal C++ for the above reasons: C++ doesn't recognize it as a
null pointer constant, so it is a null pointer of type void*.  And
unlike C, C++ doesn't allow implicit conversion of void* to T*.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Mon, 30 Oct 2000 18:41:13 GMT
Raw View
Ron Natalie <ron@sensor.com> writes:

|>  Which unforutnately, is the main arguemnt for not changing it.  The
|>  fact that zero made a good invalid pointer value is purely
|>  historical.  The idea was that you just avoid placing things at
|>  location zero (not a probelm in the origianl C implementations where
|>  there were instructions down there, but easily fixed by just skiping
|>  the first few bytes of dataspace in split I-D modes).  God save us
|>  from the second mistake, some joker puting a zero at location zero.

Most early Unix implementations did just that.  You could pass NULL as
the source to strcpy, and you would get an empty string.  I've talked to
people who thought that this was guaranteed behavior.

I remember when we changed this in our implementation -- instead of
putting a write protected page full of 0's at address 0, we simply
didn't map the page, so dereferencing a null pointer caused a core
dump.  We had to undo the change, because about have of the Unix
utilities core dumped because of it.

|>  The zero guaranteed to be converted to an appropriate null value is
|>  "cutsie" and the standards committees have gone to great lengths to
|>  write special verbage to propagate a kludge that should have never
|>  made it out of the earliest implementations of the compiler.

Agreed.  The correct time to change is when it was realized that int's
were not pointers, and that there was nothing special about the address
0.  Except that there was already a substantial body of existing code at
the time.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Mon, 30 Oct 2000 18:41:45 GMT
Raw View
Team-Rocket@gmx.net (Niklas Matthies) writes:

|>  On Sun, 15 Oct 2000 03:38:14 GMT, kanze@gabi-soft.de <kanze@gabi-soft=
.de> wrote:
|>  > wmm@fastdial.net writes:
|>  [=B7=B7=B7]
|>  > |>  1) The acceptance of "(void*)0" as a null pointer constant
|>  > |>  is consistent with, not an exception to, C's rules for
|>  > |>  pointer compatibility.

|>  > No, because C's rules don't have anything to do with pointer
|>  > compatibility.  A null pointer is a special case, and although
|>  > (void*)0 may look like casting an integral 0 to void*, it is *not*
|>  > a normal cast -- the special properties of a null pointer must be
|>  > respected.

|>  It is in fact a "normal cast".

How do you define a "normal cast".  It has the syntax of a normal cast,
but it certainly doesn't have the semantics.

|>  C defines null pointer constants by the
|>  following sentence [C99:6.3.2.3p3s1]:

|>     An integer constant expression with the value 0, or such an
|>     expression cast to type void *, is called a null pointer constant.

|>  Of course such an expression has then special properties, but the cas=
t
|>  inside is a normal one.

With regards to syntax.  The standard then goes on to define different
semantics from those of a normal cast.

|>  Furthermore, because of [C99:6.3.2.3p3s2-p4]

|>     If a null pointer constant is converted to a pointer type, the
|>     resulting pointer, called a null pointer, is guaranteed to
|>     compare unequal to a pointer to any object or function.

|>     Conversion of a null pointer to another pointer type yields a
|>     null pointer of that type. Any two null pointers shall compare
|>     equal.

|>  the expression `(void *) 0' is not only a null pointer constant, but
|>  at the same time a null pointer (because it's the null pointer
|>  constant `0' converted to a pointer type), which `0' by itself is
|>  not.

Ahah.  I see what you mean.  "(void*)0" is both --null pointer
constant--, and (void*)--null pointer constant--.  So the cast is both a
normal cast *and* one with special semantics.  (In practice, of course,
I can't imagine a program in C where the two interpretations would make
a difference.)

|>  The only effect of `(void *) 0' being a null pointer constant in C
|>  (unless I overlooked something) is
|>  (1) that it is allowed to be the expansion of the NULL macro and
|>  (2) that an expression like

|>     ( expr ? (void *) 0 : (char *) something )

|>  has type `char *' and not type `void *', because there is a special
|>  case made for null pointer constants as second or third operand to
|>  the ?: operator.

Doesn't this special case also affect void* in C?  (I'm asking; I really
don't know.  But given the implicit conversion of void* in C, it would
make sense.)

|>  > The reason it [void * 0] does work in C is because the standard
|>  > says it works.

|>  Not quite. If the C standard didn't make `(void *) 0' a null pointer
|>  constant, the only real difference would be for the ?: operator, as
|>  explained above. In all other cases where the C standard makes
|>  specific provisions for null pointer constants, a constant
|>  expression with type void * (which `(void *) <any integer constant
|>  expression>' is) would behave the same.

So I believe.  Never the less, they *did* make it a null pointer
constant.  And it must have been a conscious decision, since it wasn't
the case before standardization.  To quote K&R 1: "[...] However, it is
guaranteed that the assignment of the constant 0 to a pointer will
produce a null pointer distinguishable from a pointer to any object."
There's similar language concerning comparison.  (Note that in both
cases, K&R allows comparing a pointer to any int, and assigning any type
of pointer to any other, although the semantics are explicitly vague.)

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Mon, 30 Oct 2000 18:41:59 GMT
Raw View
Team-Rocket@gmx.net (Niklas Matthies) writes:

|>  On Sun, 15 Oct 2000 00:49:09 GMT, kanze@gabi-soft.de <kanze@gabi-soft=
.de> wrote:
|>  [=B7=B7=B7]
|>  > The fact that C allows void*->T*, and C++ doesn't, is irrelevant to=
 the
|>  > discussion, because in both C and C++, null pointer constants are
|>  > special beasts, with special rules.  (In practice, C compilers whic=
h
|>  > actually define NULL as (void*)0 are pretty much the exception.  Of
|>  > course, in this case, the one or two exceptions -- Microsoft and
|>  > Borland, do happen to be widespread.)

|>  Gcc does, too.

Normally, gcc uses the local definition (0 on my machine).  G++ uses
__null, at least under Solaris.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Mon, 30 Oct 2000 18:46:42 GMT
Raw View
kanze@gabi-soft.de wrote:
>
> Team-Rocket@gmx.net (Niklas Matthies) writes:
...
> That, of course, argues for a special key word.  Which is probably the
> best solution anyway.  But it requires a bit of effort -- if f is a
> template function, what type should f(NULL) instantiate?

That shouldn't be a difficult decision to make. It should be either
void* or ambiguous, and I doubt it would take long to come up with
arguments that show that only one of those two options is viable (I
haven't tried).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "David Thompson" <david.thompson1@worldnet.att.net>
Date: Mon, 30 Oct 2000 18:47:42 GMT
Raw View
<kanze@gabi-soft.de> wrote :
....
> You're thinking of C (where there are no rvalues).  In C++, an
> expression is either an lvalue or an rvalue, and there is an lvalue to
> rvalue conversion (implicit, of course).
>
C certainly does have rvalues and lvalues the same as C++,
with an implicit conversion:  C89 6.2.2.1; C99 6.3.2.1p2,3.
C does not have _user-defined_ conversions.

--
- David.Thompson 1 now at worldnet.att.net


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 30 Oct 2000 18:53:35 GMT
Raw View

"Douglas A. Gwyn" wrote:
>
> Ron Natalie wrote:
> > ...  The zero guaranteed to be converted to an appropriate null
> > value is "cutsie" and the standards committees have gone to great
> > lengths to write special verbage to propagate a kludge that should
> > have never made it out of the earliest implementations of the
> > compiler.
>
> if(p)... enshrined the behavior in the C language forever.

So was if(p == -1), Doug.  Early C++ pretty much interchanged
ints and pointers indescrimately.  The original C reference
manual doesn't mention null pointers anywehre.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 30 Oct 2000 19:01:46 GMT
Raw View
In article <86r95acej1.fsf@gabi-soft.de>, kanze@gabi-soft.de writes
>Well, the above is certainly the most frequent case.  Before void*, of
>course, most C compilers allowed implicit conversions between all
>pointer types, precisely so that the above would not need a cast.

Not any C compiler that I ever used (or at least not in any mode that I
would have used it) Implicit conversions of pointers is pure poison.

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

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: Mon, 30 Oct 2000 19:22:27 GMT
Raw View
David R Tribble <david@tribble.com> writes:

| >> If the above code would be legal C, why make
| >> the dispensation for (void *)0
|
| Valentin Bonnard <Valentin.Bonnard@free.fr> writes:
| >> Probably to allow C++ to define NULL as (void*)0 instead
| >> of the ugly (and not type safe) 0.
|
| Gabriel Dos Reis wrote:
| >> That would allow `(void *)0' but would not prohibit `0'.  Thus
| >> instead of one hack, we will have two hacks for spelling the same
| >> thing.
|
| Ron Natalie wrote:
| > Agreed.  If we are going to allow funky sequences such as zeros cast
| > to void* meaning NULL POINTER CONSTANT, why don't we just define an
| > explicit literal like "NULL" or "__null" to be the constant.
|
| The addition of a new keyword or special identifier (e.g., 'null',
| '__null__', or simply 'NULL') for both C and C++ has been suggested
| several times in the past.  But no one seems convinced or moved enough
| to actually get this into the language.  (C++ needs it far more than
| C.)

Probably because adding a new keyword won't prohibit 0 to be
interpreted as a null pointer constant? Or are you also proposing to
prohibit 0 as a NPC?

--
Gabriel Dos Reis                    gdr@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
     http://www.codesourcery.com/gcc-compile.shtml

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Mon, 30 Oct 2000 19:26:46 GMT
Raw View
>> Now what's with the null pointer constant? For convenience, you want
>> it to be really generic, similar to singleton type. You still want
>> the same behaviour (i.e. no explicit conversions needed) as all void
>> pointers had in C all along. Allowing (void *) 0, which is fairly
>> commonly used for NULL in C implementations since pre-ANSI times,
>> was't practical in C++ anymore, because an explicit cast would be
>> needed upon assignment to any pointer type other than void *.

Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:
>> That's simply not correct.  If `(void *)0' was a null pointer
>> constant, then there would be no need for an explicit cast when
>> assigning it to some other pointer type, just as there is no
>> need for an explicit cast when assigning `0' to a pointer type.

Niklas Matthies wrote:
> To quote Stroustrup from D&E-11.2.3:
>=20
>    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.
>    Also, C++ usage was determined long before there was an ANSI C
>    standard, and I do not want to have any critical part of C++ rely
>    on a macro (=A718). Consequently, I used plain 0, and that has worke=
d
>    very well over the years.
>=20
> There's more, but this is the essential paragraph. One can disagree
> with this rationale (I'm myself not sure that I completely agree),
> but this _is_ the rationale why it is how it is today.

As it is now, '((void*)0' is treated exactly like any other pointer
cast to 'void*'.  But, as has been suggested several times in the past
in news:comp.std.c++, Bjarne could have made '((void*)0)' be a special
case, and allowed it to be treated as a [generic] null pointer
constant.

The benefits of this are (as previously mentioned many times before):

1. NULL could be #defined as '((void*)0)' in both C and C++.

2. The uses of NULL (or '((void*)0)') would be more type-safe than
 '0' in both C and C++.

3. The uses of NULL (or '((void*)0)') would be less ambiguous than
 '0' in C++.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Mon, 30 Oct 2000 19:27:09 GMT
Raw View
Nick Maclaren wrote:
> Yes, I agree that this mess ought to be cleaned up.  But it is a
> waste of time trying to get to a strongly typed language starting
> from C, and it will merely cause trouble if it is attempted.

History would disagree.

C++ was derived from C, and is much more type-safe than C.
Java was derived from C, and Java is a type-safe language.

If, on the other hand, you meant that trying to make [some future
version of] C a type-safe language is a waste of time, then yes,
that's probably true.  On the other other hand, C89 is much more
type-safe than K&R C.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Mon, 30 Oct 2000 19:32:20 GMT
Raw View
"David R Tribble" <david@tribble.com> wrote

> The addition of a new keyword or special identifier (e.g., 'null',
> '__null__', or simply 'NULL') for both C and C++ has been suggested
> several times in the past.  But no one seems convinced or moved enough
> to actually get this into the language.  (C++ needs it far more than
> C.)

I'd definitely vote in favour.

I think some of the actual voters are present her, thet could enlighten why
such a specialised npc would be bad.

Paul



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Dennett <james@evtechnology.com>
Date: Mon, 30 Oct 2000 20:13:03 GMT
Raw View
kanze@gabi-soft.de wrote:

> David R Tribble <david@tribble.com> writes:
>
> |>  Using NULL at least has the benefits of 1) looking like a null
> |>  pointer, even if it really isn't underneath, and 2) standing a
> |>  better chance of continuing to compile if NULL ever becomes a real
> |>  type-safe null pointer constant and 0 becomes just an int.
>
> Realistically, there will never be a time when 0 will not convert
> implicitly to a null pointer.  About the best we can hope for is a real
> null, which *if* used might prevent some errors, and would certainly be
> more readable.  I don't think it reasonable to require all existing code
> to be modified to use this new feature, however.

I do think it reasonable to require that C++ compilers should, at some time
in the future, be required to support two compilation modes for C++.  One
would be there to allow legacy features (such as 0 as an NPC and the implicit
conversion from string literal to non-const "char *") and the other to allow
for safer compilation.

Right now we have only the sledgehammer of deprecation with which to hit
these problems, and there is (IMO) too much resistance to deprecating
widely used features.  That resistance is somewhat understandable, but also
damaging.  Implementations are clearly allowed to issue diagnostics for such
legacy features, and QoI should put pressure on implementors to allow
warnings to be turned on/off to suit, but I believe that the C++ Standard
might be strengthened if for certain pieces of code it required compilers
to be able to both compile the code and also to issue a diagnostic.  AFAIK
whenever the C++ Standard of today requires a diagnostic the compiler is
allowed to fail to compile the source code.

Now I feel I must go to a Java forum and complain about inappropriate use
of @deprecated in javadoc comments...

-- James Dennett <jdennett@acm.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Douglas A. Gwyn" <DAGwyn@null.net>
Date: 2000/10/22
Raw View
Ron Natalie wrote:
> ...  The zero guaranteed to be converted to an appropriate null
> value is "cutsie" and the standards committees have gone to great
> lengths to write special verbage to propagate a kludge that should
> have never made it out of the earliest implementations of the
> compiler.

if(p)... enshrined the behavior in the C language forever.

In fact the C standard works hard to *not* guarantee that a 0
value converted to a pointer can be used as a null pointer:
int i = 0, *ip = (int *)i; if(ip)... // doesn't necessarily skip

Null pointer constant is a carefully crafted technical term
that applies *only* in certain well-defined contexts, and in
those contexts something that looks *syntactically* like a
cast of a zero integer value to a pointer is treated specially
as a null pointer constant, which is one form of null pointer
(called "nil" in some other languages).  In other contexts,
such as the above example, an apparent conversion of a zero
value to a pointer does *not* necessarily produce a null pointer.

A language designed from scratch should take into account
lessons learned from the many infelicities of C and other
languages.  (I have a long list of such areas of improvement.)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/10/22
Raw View
kanze@gabi-soft.de wrote:
...
> constant converts implicitly to any type of pointer.  And there is
> otherwise *no* type in C++ which converts implicitly to any type of
> pointer.  A null pointer constant is a special case, any way you look at
> it.

It is, however, possible within C++ to define a type that does
implicitly convert to any pointer type, and only to pointer types.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: 2000/10/22
Raw View
On Sun, 22 Oct 2000 11:56:39 GMT, kanze@gabi-soft.de <kanze@gabi-soft.de>=
 wrote:
> Team-Rocket@gmx.net (Niklas Matthies) writes:
>=20
> |>  To quote Stroustrup from D&E-11.2.3:
>=20
> |>     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 f=
or
> |>     (void *) 0, but special cases should only be admitted in dire ne=
ed.
> |>     Also, C++ usage was determined long before there was an ANSI C
> |>     standard, and I do not want to have any critical part of C++ rel=
y on
> |>     a makro (=A718). Consequently, I used plain 0, and that has work=
ed very
> |>     well over the years.
>=20
> The quoted text is a justification of an existing situation, not an
> explination of how it came about (except for the bit about Bjarne's
> using plain 0).  In fact, of course, the special case is there,
> regardless of how you spell a null pointer constant.  A null pointer
> constant converts implicitly to any type of pointer.

This is not accurate. A `null pointer constant' is just a syntactical
construct. In C, it's type is int when it's just a integer constant
expresseion with value 0, and void * when it was cast to void *.

The standard says that *if* a null pointer constant is converted to some
pointer type, *then* the result is a null pointer value. But there is
*no* general rule that allows such a conversion to be performed
implicitly. All valid implicit conversions of null pointer constants are
due to the surrounding syntactical constructs (i.e. assignment,
comparison etc.) having special provisions for null pointer constants.

So, the special case is actually a lot of special cases sprinkled
throughout the standard.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kanze@gabi-soft.de
Date: 2000/10/22
Raw View
"Douglas A. Gwyn" <DAGwyn@null.net> writes:

|>  Null pointer constant is a carefully crafted technical term
|>  that applies *only* in certain well-defined contexts, and in
|>  those contexts something that looks *syntactically* like a
|>  cast of a zero integer value to a pointer is treated specially
|>  as a null pointer constant, which is one form of null pointer
|>  (called "nil" in some other languages).  In other contexts,
|>  such as the above example, an apparent conversion of a zero
|>  value to a pointer does *not* necessarily produce a null pointer.

The problem, of course, is that the spelling of nil in C and C++ is
ambiguous.  One of the spellings can be interpreted as an integer, and
it will be so interpreted, in preference to nil, in a context where an
integer is allowed.

This is not a real problem in C.  Off hand, no ambiguous contexts come
to mind.  There may be one, but it doesn't strike the average
programmer.  I found the C solution inelegant, but not particularly
troublesome.  In C++, on the other hand, function overloading and
templates mean that the ambiguity rears its head all to frequently.
This is certainly one reason that some very competent programmers
recommend using 0 instead of NULL -- at least the hack is visible.  And
it is certainly the reason why people like myself are far more motivated
to correct the problem -- I simply cannot bring myself to think of 0 as
a pointer.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: 2000/10/22
Raw View
On Sun, 22 Oct 2000 21:34:33 GMT, kanze@gabi-soft.de <kanze@gabi-soft.de>=
 wrote:
> "Douglas A. Gwyn" <DAGwyn@null.net> writes:
[=B7=B7=B7]
> The problem, of course, is that the spelling of nil in C and C++ is
> ambiguous.  One of the spellings can be interpreted as an integer, and
> it will be so interpreted, in preference to nil, in a context where an
> integer is allowed.
>=20
> This is not a real problem in C.  Off hand, no ambiguous contexts come
> to mind.

In C, the type of expressions like

   expr ? NULL : NULL

(which may arise non-trivially as a result from macro expansions)
are implementation-dependent, and in a context like

   void *p =3D expr ? NULL : NULL;

are invalid if NULL expands to an integer constant expression.
Of course, such cases are usually quite rare.

-- Niklas
   (who apologizes for all the spelling errors in his previous postings)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/10/25
Raw View
Paul Jarc wrote:
> If ((void*)0) were not a null pointer constant in
> C, it would still be a null pointer, but NULL could not be defined as
> ((void*)0), so NULL would always be an integer constant expression
> with a value of 0, and so 'int i=NULL;' would work - unless the
> wording for NULL were changed to allow it to be a
> non-null-pointer-constant null pointer.  So if it were desired that
> 'int i=NULL;' should not be allowed, that could be accomplished by
> allowing NULL to be defined with other than integer type.

FWIW, I proposed to the ISO C9X committee that the definition of
the 'NULL' macro be revised slightly to require it to be a null
pointer constant "of pointer type".  My intent was to disallow
integer constants as NULL and thus to favor '((void*)0)' or its
equivalent.

The committee rejected my proposal.

See <http://david.tribble.com/text/c9xc005.txt>.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/10/25
Raw View
>> If the above code would be legal C, why make
>> the dispensation for (void *)0

Valentin Bonnard <Valentin.Bonnard@free.fr> writes:
>> Probably to allow C++ to define NULL as (void*)0 instead
>> of the ugly (and not type safe) 0.

Gabriel Dos Reis wrote:
>> That would allow `(void *)0' but would not prohibit `0'.  Thus
>> instead of one hack, we will have two hacks for spelling the same
>> thing.

Ron Natalie wrote:
> Agreed.  If we are going to allow funky sequences such as zeros cast
> to void* meaning NULL POINTER CONSTANT, why don't we just define an
> explicit literal like "NULL" or "__null" to be the constant.

The addition of a new keyword or special identifier (e.g., 'null',
'__null__', or simply 'NULL') for both C and C++ has been suggested
several times in the past.  But no one seems convinced or moved enough
to actually get this into the language.  (C++ needs it far more than
C.)

See my own contribution (Nov 1997) to the ongoing argument at:
<http://david.tribble.com/text/c9xnull.txt>.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/10/25
Raw View

David R Tribble wrote:
>

> The addition of a new keyword or special identifier (e.g., 'null',
> '__null__', or simply 'NULL') for both C and C++ has been suggested
> several times in the past.  But no one seems convinced or moved enough
> to actually get this into the language.  (C++ needs it far more than
> C.)
>
> See my own contribution (Nov 1997) to the ongoing argument at:
> <http://david.tribble.com/text/c9xnull.txt>.
>
>
Yeah, I know how it is, 25 years of sloppy programming style to overcome.
I learned assembler first, so I didn't mind the 0 pointer value, until
I really started getting into better typesafety of C++.  I'm willing to
give up on C, C++ should have a explicit null pointer literal.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/10/25
Raw View
Paul Jarc wrote:
>> But removing the null pointer constant status of 0 and (void*)0
>> would break existing code.

Ron Natalie wrote:
> Which unforutnately, is the main arguemnt for not changing it.

No one is suggested eliminating the current semantics of allowing 0 to
be used as a null pointer constant.  Yet.

Some of sus are, however, suggesting that a new keyword or special
identifier ('__null__', 'null', 'NULL', or whatever) be introduced
that operates as a (better) type-safe null pointer constant.  (In C++
anyway; C isn't perfect, but it's okay as it is.)

Deprecating the use of zero as null would then be the next step.  But
this wouldn't, nor couldn't, happen overnight.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/10/25
Raw View
kanze@gabi-soft.de wrote:
> This is certainly one reason that some very competent programmers
> recommend using 0 instead of NULL -- at least the hack is visible.
> And it is certainly the reason why people like myself are far more
> motivated to correct the problem -- I simply cannot bring myself to
> think of 0 as a pointer.

Me neither.  And using 0 for null simply propogates the hack.

Using NULL at least has the benefits of 1) looking like a null pointer,
even if it really isn't underneath, and 2) standing a better chance of
continuing to compile if NULL ever becomes a real type-safe null
pointer constant and 0 becomes just an int.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: John Rickard <jrr@255.255.255.192>
Date: 2000/10/25
Raw View
In comp.std.c Niklas Matthies <Team-Rocket@gmx.net> wrote:
: The only effect of `(void *) 0' being a null pointer constant in C
: (unless I overlooked something) is
[snipped]

Also, a null pointer constant can be assigned to a pointer to
function, whereas an ordinary void* can't:

  void (*pf)();
  void *pnull = 0;
  pf = (void *)0;  /* OK in C */
  pf = pnull;      /* Syntax error */

--
John Rickard   <John.Rickard@virata.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kanze@gabi-soft.de
Date: Sat, 28 Oct 2000 17:15:15 GMT
Raw View
James Kuyper <kuyper@wizard.net> writes:

|>  kanze@gabi-soft.de wrote:
|>  ...
|>  > constant converts implicitly to any type of pointer.  And there is
|>  > otherwise *no* type in C++ which converts implicitly to any type of
|>  > pointer.  A null pointer constant is a special case, any way you lo=
ok at
|>  > it.

|>  It is, however, possible within C++ to define a type that does
|>  implicitly convert to any pointer type, and only to pointer types.

At the cost of one user defined conversion -- which will affect overload
resolution, and may in some cases render an otherwise legal program
illegal.  (Typically, of course, in a well written program, you won't
notice.)

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Sat, 28 Oct 2000 17:15:48 GMT
Raw View
Team-Rocket@gmx.net (Niklas Matthies) writes:

|>  On Sun, 22 Oct 2000 11:56:39 GMT, kanze@gabi-soft.de <kanze@gabi-soft=
.de> wrote:
|>  > Team-Rocket@gmx.net (Niklas Matthies) writes:

|>  > |>  To quote Stroustrup from D&E-11.2.3:

|>  > |>     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.  Also,
|>  > |>     C++ usage was determined long before there was an ANSI C
|>  > |>     standard, and I do not want to have any critical part of
|>  > |>     C++ rely on a makro (=A718). Consequently, I used plain 0,
|>  > |>     and that has worked very well over the years.

|>  > The quoted text is a justification of an existing situation, not
|>  > an explination of how it came about (except for the bit about
|>  > Bjarne's using plain 0).  In fact, of course, the special case is
|>  > there, regardless of how you spell a null pointer constant.  A
|>  > null pointer constant converts implicitly to any type of pointer.

|>  This is not accurate. A `null pointer constant' is just a
|>  syntactical construct. In C, it's type is int when it's just a
|>  integer constant expresseion with value 0, and void * when it was
|>  cast to void *.

I believe that is exactly what I said.

It is a special case regardless of its type.  Explicitly converting an
integer with the value of 0 may give different results than converting a
null pointer constant, even though 0 is a null pointer constant.

|>  The standard says that *if* a null pointer constant is converted to
|>  some pointer type, *then* the result is a null pointer value. But
|>  there is *no* general rule that allows such a conversion to be
|>  performed implicitly. All valid implicit conversions of null pointer
|>  constants are due to the surrounding syntactical constructs
|>  (i.e. assignment, comparison etc.) having special provisions for
|>  null pointer constants.

|>  So, the special case is actually a lot of special cases sprinkled
|>  throughout the standard.

I'm not sure what point you are trying to make.  The same is true for
just about every implicit conversion: integral promotions only take
place where specified, for example.  What makes the null pointer
constant a special case is the fact that it only affects a very limited
subset of expressions of the given type.  If I explicitly cast an int to
a pointer value, the results may be different if the int expression
happens to be a null pointer value.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Sun, 29 Oct 2000 02:58:34 GMT
Raw View
David R Tribble <david@tribble.com> writes:

|>  Using NULL at least has the benefits of 1) looking like a null
|>  pointer, even if it really isn't underneath, and 2) standing a
|>  better chance of continuing to compile if NULL ever becomes a real
|>  type-safe null pointer constant and 0 becomes just an int.

Realistically, there will never be a time when 0 will not convert
implicitly to a null pointer.  About the best we can hope for is a real
null, which *if* used might prevent some errors, and would certainly be
more readable.  I don't think it reasonable to require all existing code
to be modified to use this new feature, however.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: Mon, 30 Oct 2000 17:44:50 GMT
Raw View
prj@po.cwru.edu (Paul Jarc) writes:

>Ron Natalie <ron@sensor.com> writes:
>> Agreed.  If we are going to allow funky sequences such as zeros cast to void*
>> meaning NULL POINTER CONSTANT, why don't we just define an explicit literal
>> like "NULL" or "__null" to be the constant.
>
>That's easily done by implementations:
>    enum { __null=0 };
>    #define NULL ((void*)__null) /* or just __null for C++ */
>But removing the null pointer constant status of 0 and (void*)0 would
>break existing code.

In C++, enumeration constants like `__null' are not null pointer constants.
The C++ standard says "A null pointer constant is an integral constant
expression rvalue OF INTEGER TYPE that evaluates to zero." (4.10p1).
In C++ enumeration constants have enumeration type, not integer type.

Another incompatibility between C and C++...

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Valentin Bonnard <Valentin.Bonnard@free.fr>
Date: Mon, 30 Oct 2000 17:48:50 GMT
Raw View
[ Message still cross-posted. ]

Paul Jarc wrote:

> Valentin Bonnard <Valentin.Bonnard@free.fr> writes:
> > James Dennett wrote:
> (regarding C)
> > > why make the dispensation for (void *)0
> >
> > Probably to allow C++ to define NULL as (void*)0 instead
> > of the ugly (and not type safe) 0.
>
> If so, that would make it a failed effort.

Indeed. We, C++ programmers/designers, often blame the C
heritage for the ugly syntax and the misfeatures of C++.
This time, we can only blames ourselves (and The Big Chief,
B.S.).

> > > -- is this just to ensure that the
> > > following code is non-portable?
> > >
> > > int i = NULL;
> >
> > You mean in C ? Well, this is code certainly is non-portable
> > in C, and asking why doesn't make much sens (it is non-portable
> > because people wan't it not to be portable).
>
> No, it makes sense.

I meant that the details of the machinary are less important
than the intent or the result. The result is that it is non-
portable, and that's the intent (at least, I strongly believe
so).

> > The problem with allowing only ``integer constant expressions
> > with the value 0'' as null pointer constants is that the
> > following wouldn't be valid:
> >
> >   #define NULL ((void*)0)
> >   static int *p = NULL;
>
> Are you talking about C or C++ here?

None. I am talking about an imaginary language: C, changed to allow
only C++-like null pointer constants (NPC), that is ``integer constant
expressions with the value 0''.

> It's already invalid in C++,

Yes, but that isn't my point.

> and only the definition of NULL would become invalid in C ('static int *p=0;'
> would still be ok),

Yes.

> which makes me wonder what the int* declaration is
> there for.

To show a motivation for making (void*)0 a NPC in C. W/o this
rule, such code:

  static int* p = (void*)0;

wouldn't be valid C because the C compiler wants a constant
expression after the equal sign.

--

Valentin Bonnard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Andrew J Robb <andrew@localhost.localdomain.screaming.net>
Date: Mon, 30 Oct 2000 18:25:39 GMT
Raw View
I searched the ISO/IEC-14482:1998 standard and found no reference to NULL except within the C library.
So unless you are using the standard C library, you do not have access to a definition of 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Sun, 15 Oct 2000 03:38:14 GMT
Raw View
wmm@fastdial.net writes:

|>  The following facts are indisputable:

|>  1) In C, an expression of type "void*" can be assigned to any
|>  pointer.

True, but irrelevant.  The reason (void*)0 works as a null pointer
constant in C has nothing to do with what you can or cannot do with
void*.  To work as a null pointer constant requires more than just being
assignable to any pointer -- if that were the case, then 0 would not be
a null pointer constant in C.

|>  2) In C++, as currently constituted, an expression of type
|>  "void*" cannot be assigned to pointers whose type is not
|>  "void*."

Again, irrelevant.  No one has ever suggested changing this.

|>  3) The type of "(void*)0" is "void*".

Exactly as the type of 0 is int.  Again, I fail to see the connection.

|>  4) Some change to the definition of C++ would be required to
|>  permit "(void*)0" to be assignable to non-void* pointers.

Agree.  Because originally C++ didn't define (void*)0 as a null pointer
constant, allowing it would be a change.  If C++ had originally that
only (void*)0 was a null pointer constant, then allowing 0 would be a
change.

What is your point?

|>  Exactly what change would be required, how significant that change
|>  would be, and whether the change is desirable or not are areas of
|>  legitimate difference of opinion.  You're right, there's "no
|>  technical reason it couldn't have been done in C++" -- I never
|>  suggested otherwise -- but there is room for disagreement about
|>  whether it _should_ have been done.

Just as there's room for disagreement as to whether 0 should have been
allowed as a null pointer constant to begin with.

We have a historical situation.  I agree that to justify a change, some
improvement must be shown.

|>  Whether "(void*)0" works in C because of the pointer compatibility
|>  or because of its explicit definition as a null pointer constant is,
|>  I think, not a very fruitful area of discussion.  Having phrased my
|>  comment the way I did was probably unfortunate.  The two points I
|>  had in mind with that statement were:

|>  1) The acceptance of "(void*)0" as a null pointer constant
|>  is consistent with, not an exception to, C's rules for
|>  pointer compatibility.

No, because C's rules don't have anything to do with pointer
compatibility.  A null pointer is a special case, and although (void*)0
may look like casting an integral 0 to void*, it is *not* a normal cast
-- the special properties of a null pointer must be respected.

|>  2) The reason "(void*)0" _doesn't_ work in C++ is a direct
|>  consequence of the difference between the pointer compatibility
|>  rules of C and C++.

The reason (void*)0 doesn't work in C++ is because the standard says it
doesn't work.  The reason it does work in C is because the standard says
it works.

|>  As for the point about integer 0 being incompatible with pointer
|>  types, I completely agree.  Unfortunately, we're stuck with that
|>  because of C compatibility (direct use in the source, not mediated
|>  by the "NULL" preprocessor symbol).  That doesn't mean I have to
|>  like "(void*)0" any better, though.

In the end, the question isn't whether one likes one notation or the
other.  The problem is, we are stuck with a certain number of notations
for historical reasons.  I think we both agree that we can't, today,
change the standard to say that 0 is not a null pointer constant, as
much as some of us think it might be an improvement.  The question is,
can we improve what we have, and how?

I was the author of the actual proposale for (void*)0.  At the time, I
thought that we were in the final phases of the standard; I didn't know
that STL would come along, and delay everything.  And I didn't want to
delay the standard any more than necessary.  So I proposed something
that gave a small improvement, at almost no cost.  Because allowing
(void*)0 as a null pointer constant, and requiring NULL to be defined
this way, while extremely ugly (I agree with Bill Millers esthetic
evaluation) has almost no cost, and is simple.  And it does prevent
using NULL as an integer, which is better than nothing.

Personally, what I'd like best is a real null pointer, with the current
null pointer constant deprecated.  Practically, that's a lot of work to
define -- what happens with templates, etc.  Still, since we are now
talking about the next version of the standard, I think it would be
worthwhile to see what can be done in this direction.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Sun, 15 Oct 2000 03:38:34 GMT
Raw View
Ron Natalie <ron@sensor.com> writes:

|>  Jim Hyslop wrote:

|>  > Assuming that the compiler defines __null to be the equivalent of:

|>  > const int __null=3D0;

|>  > what would make that non-conforming? It's still an integral constan=
t
|>  > expression evaluating to zero.

|>  I think the issue was if NULL were to be some magic cookie that
|>  behaved like a null pointer constant when compared/assigned to
|>  pointers, but did not behave like an integer when used otherwise.

I think that this would be legal too, as long as in conforming mode, it
gave the same results as an integral constant expression evaluating to
0.  The advantage, of course, is that even in conforming mode, the
compiler could issue warnings whenever the value *wasn't* used as a
pointer.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Dennett <jdennett@acm.org>
Date: 2000/10/15
Raw View
kanze@gabi-soft.de wrote:
>
> wmm@fastdial.net writes:
>
> |>  2) The reason "(void*)0" _doesn't_ work in C++ is a direct
> |>  consequence of the difference between the pointer compatibility
> |>  rules of C and C++.
>
> The reason (void*)0 doesn't work in C++ is because the standard says it
> doesn't work.  The reason it does work in C is because the standard says
> it works.
>

Here I confess to being mystified.

Suppose C didn't say that (void *)0 was a NPC.  Wouldn't it still be
legal (in C) to write

struct X *p = (void *)0;

simply because 0 is a NPC, so (void *)0 is a null pointer, and (void*)
converts (in C) to (X*)?  If the above code would be legal C, why make
the dispensation for (void *)0 -- is this just to ensure that the
following code is non-portable?

int i = NULL;

Ugly code for sure, but it would also be ugly to say that its legality
is implementation-defined.  I'd prefer it to be outright illegal (maybe
in the next revision of the C++ Standard?  Please?!) but if that can't
be so then at least C++ defined it consistently across all compilers
which conform in this respect.

-- James Dennett <jdennett@acm.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: "Sebastian Moleski" <sebmol@gmx.net>
Date: 2000/10/15
Raw View
"James Dennett" <james@evtechnology.com>:
| michael wrote:
...
| I sometimes wish that there were two modes defined by Standard C++ --
backwards (C-compatible) mode, and sensible (safe) mode.  I dread to think
how much compexity this would have added to the standardization process
though.  It would be nice to deprecate
| implicit conversions to bool at some time in the future, and I'd be for
redefining "null pointer constant" at that time to mean something like
"__null_pointer_constant", which would be a new reserved word.  Probably
more experienced people can think of
| better ways to get rid of this overloading of 0.

If I was to decide, you had my vote against it. I sometimes write code like
the following where an explicit comparison with 0 would be just plain ugly:

// current way
if (const SomeClass *c = dynamic_cast<const SomeClass *>(o)) {
}

// your way
if ((const SomeClass *c = dynamic_cast<const SomeClass *>(o)) ==
__null_pointer_constant) {
}

I think the first one makes totally clear what is expected to happen without
the need for explicit comparison.

Of course, this issue has been discussed to no end already and IMO there
really is no need to open it up again.

sm



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Balog Pal" <pasa@lib.hu>
Date: 2000/10/16
Raw View
<kanze@gabi-soft.de> wrote
>>
Personally, what I'd like best is a real null pointer, with the current
null pointer constant deprecated.  Practically, that's a lot of work to
define -- what happens with templates, etc.  Still, since we are now
talking about the next version of the standard, I think it would be
worthwhile to see what can be done in this direction.
<<

I too think it would have been much better to introduce a new special
keyword, like __null or something that is the_null_pointer_constant. And
which is treated as an universal type pointer by the compiler, compares as
is should, etc. NULL then could be #define'd to that or be decrepated.

But now is not then. With the way C++ is and was tons of code use plain 0,
and not NULL or some other replacement, so stopping the integer 0 from work
as npc would break almost all programs out there. So I'm sure that will
never change, at least not in the next 10 years.

Paul




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Valentin Bonnard <Valentin.Bonnard@free.fr>
Date: 2000/10/17
Raw View
[ Please notice the fu2 and follow it, or not, according to the subject
of your answer. ]

James Dennett wrote:
>
> kanze@gabi-soft.de wrote:
> >
> > wmm@fastdial.net writes:
> >
> > |>  2) The reason "(void*)0" _doesn't_ work in C++ is a direct
> > |>  consequence of the difference between the pointer compatibility
> > |>  rules of C and C++.
> >
> > The reason (void*)0 doesn't work in C++ is because the standard says it
> > doesn't work.  The reason it does work in C is because the standard says
> > it works.
> >
>
> Here I confess to being mystified.
>
> Suppose C didn't say that (void *)0 was a NPC.  Wouldn't it still be
> legal (in C) to write
>
> struct X *p = (void *)0;

Yes, it would.

> If the above code would be legal C, why make
> the dispensation for (void *)0

Probably to allow C++ to define NULL as (void*)0 instead
of the ugly (and not type safe) 0.

> -- is this just to ensure that the
> following code is non-portable?
>
> int i = NULL;

You mean in C ? Well, this is code certainly is non-portable
in C, and asking why doesn't make much sens (it is non-portable
because people wan't it non to be portable).

The problem with allowing only ``integer constant expressions
with the value 0'' as null pointer constants is that the
following wouldn't be valid:

  #define NULL ((void*)0)
  static int *p = NULL;

which is, to say the least, annoying (and reminds me why
C isn't my favorite language).

--

Valentin Bonnard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: 2000/10/17
Raw View
[Still crossposted since it concerns both languages.]

On Tue, 17 Oct 2000 18:16:31 GMT, Valentin Bonnard <Valentin.Bonnard@free=
.fr> wrote:
> James Dennett wrote:
[=B7=B7=B7]
> > Suppose C didn't say that (void *)0 was a NPC.  Wouldn't it still be
> > legal (in C) to write
> >=20
> > struct X *p =3D (void *)0;
>=20
> Yes, it would.
>=20
> > If the above code would be legal C, why make
> > the dispensation for (void *)0=20
>=20
> Probably to allow C++ to define NULL as (void*)0 instead=20
> of the ugly (and not type safe) 0.

You may be mixing up things here (I'm not sure).

First, C++ is not allowed to define NULL as (void*)0, because that's not
a null pointer constant in C++. Secondly, 0 is not ugly (ok, YMMV), and
the missing "type safety", or rather type specificness, is the very
reason why (void *) 0 is not a null pointer constant in C++ (as opposed
to in C).

In C, void * is a generic pointer type that can be assigned to or from
any other data pointer type, i.e. without casting. This is intentional,
and the very reason void * was introduced in the first place (fomerly,
char * was used for this purpose, which needed to be casted from or to
other pointer types). I.e. in C, you write

   int *p =3D malloc(500);

without a cast. You don't want a cast there. In C, a cast says to the
human reader "look, I'm doing something special/tricky here" and to the
compiler "I know what I'm doing, don't generate diagnostics". But
conversions from and to void * in C are so commonplace that it isn't
considered something special or out-of-the-ordinary, therefore having to
use a cast wouldn't be appropriate.

In C++, conversions from and to void * are much less common, and
Stroustrup considered these implicit conversion to be a serious hole in
the type system, and therefore decided to require explicit conversions
in C++. Probably resolving ambiguities with overloading and such was
also an issue.

Now what's with the null pointer constant? For convenience, you want it
to be really generic, similar to singleton type. You still want the same
behaviour (i.e. no explicit conversions needed) as all void pointers had
in C all along. Allowing (void *) 0, which is fairly commonly used for
NULL in C implementations since pre-ANSI times, was't practical in C++
anymore, because an explicit cast would be needed upon assignment to any
pointer type other than void *. Therefore there's the requirement in C++
that a null pointer constant is just an integer constant expression,
without a cast operator.

And the reason that "0" is a null pointer constant in C comes from the
time when C had't void * yet. A _generic_ null pointer constant was
wanted, and since casting it to _any_ pointer type (like, say, char *)
would make it non-generic (i.e. further casts would be needed to convert
it other types anyway), it made most sense to leave it at just "0".
After the introduction of void *, plain "0" as a null pointer constant
in turn wasn't really needed any more, because now there was void * to
express genericness, but of course it was and is still being used, and
many C programmers even think it's preferable to "(void *) 0" for a
couple of reasons.

[I am not entirely sure with all that historical stuff, but that's how I
came to understand it. Maybe Dennis Ritchie can shed more light.]

[=B7=B7=B7]
> The problem with allowing only ``integer constant expressions=20
> with the value 0'' as null pointer constants is that the=20
> following wouldn't be valid:
>=20
>   #define NULL ((void*)0)
>   static int *p =3D NULL;
>=20
> which is, to say the least, annoying (and reminds me why=20
> C isn't my favorite language).

It's C++ that allows only ``integer constant expressions with the value
0'' as null pointer constants and makes the above code invalid in C++.
If you find this annoying, then you should blame C++, not C.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: 2000/10/18
Raw View
Valentin Bonnard <Valentin.Bonnard@free.fr> writes:

[...]

| > If the above code would be legal C, why make
| > the dispensation for (void *)0
|
| Probably to allow C++ to define NULL as (void*)0 instead
| of the ugly (and not type safe) 0.

That would allow `(void *)0' but would not prohibit `0'.  Thus instead
of one hack, we will have two hacks for spelling the same thing.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/10/18
Raw View
Team-Rocket@gmx.net (Niklas Matthies) writes:
>Valentin Bonnard <Valentin.Bonnard@free.fr> wrote:
>> James Dennett wrote:
>[...]
>> > Suppose C didn't say that (void *)0 was a NPC.  Wouldn't it still be
>> > legal (in C) to write
>> >
>> > struct X *p = (void *)0;
>>
>> Yes, it would.
>>
>> > If the above code would be legal C, why make
>> > the dispensation for (void *)0
>>
>> Probably to allow C++ to define NULL as (void*)0 instead
>> of the ugly (and not type safe) 0.
>
>You may be mixing up things here (I'm not sure).

I don't think so; I think Valentin Bonnard's comment there was
probably intended to be ironic.

>First, C++ is not allowed to define NULL as (void*)0, because that's not
>a null pointer constant in C++.

Yes, hence the irony ;-)

>Secondly, 0 is not ugly (ok, YMMV),

YMMV indeed.  Certainly `0' is not ugly in and of itself, but many
people consider using `0' as a null pointer constant to be ugly.

>and the missing "type safety", or rather type specificness, is the very
>reason why (void *) 0 is not a null pointer constant in C++ (as opposed
>to in C).

I feel compelled to disagree.  But I'm afraid that I might be
repeating myself.  If you're reading this on comp.std.c, please see
the earlier discussion on comp.std.c++.

>In C, void * is a generic pointer type that can be assigned to or from
>any other data pointer type, i.e. without casting. This is intentional
...
>In C++, conversions from and to void * are much less common, and
>Stroustrup considered these implicit conversion to be a serious hole in
>the type system, and therefore decided to require explicit conversions
>in C++.

That is fine and good.  But why did he decide to make `(void *)0'
not be a null pointer constant?  It can't have been for reasons
of type safety, since allowing `(void *)0' as a null pointer constant
would make things more type-safe, not less type-safe.

>Now what's with the null pointer constant? For convenience, you want it
>to be really generic, similar to singleton type. You still want the same
>behaviour (i.e. no explicit conversions needed) as all void pointers had
>in C all along. Allowing (void *) 0, which is fairly commonly used for
>NULL in C implementations since pre-ANSI times, was't practical in C++
>anymore, because an explicit cast would be needed upon assignment to any
>pointer type other than void *.

That's simply not correct.  If `(void *)0' was a null pointer
constant, then there would be no need for an explicit cast when
assigning it to some other pointer type, just as there is no
need for an explicit cast when assigning `0' to a pointer type.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/10/18
Raw View
Valentin Bonnard <Valentin.Bonnard@free.fr> writes:
> James Dennett wrote:
(regarding C)
> > why make the dispensation for (void *)0
>
> Probably to allow C++ to define NULL as (void*)0 instead
> of the ugly (and not type safe) 0.

If so, that would make it a failed effort.

> > -- is this just to ensure that the
> > following code is non-portable?
> >
> > int i = NULL;
>
> You mean in C ? Well, this is code certainly is non-portable
> in C, and asking why doesn't make much sens (it is non-portable
> because people wan't it non to be portable).

No, it makes sense.  If ((void*)0) were not a null pointer constant in
C, it would still be a null pointer, but NULL could not be defined as
((void*)0), so NULL would always be an integer constant expression
with a value of 0, and so 'int i=NULL;' would work - unless the
wording for NULL were changed to allow it to be a
non-null-pointer-constant null pointer.  So if it were desired that
'int i=NULL;' should not be allowed, that could be accomplished by
allowing NULL to be defined with other than integer type.

> The problem with allowing only ``integer constant expressions
> with the value 0'' as null pointer constants is that the
> following wouldn't be valid:
>
>   #define NULL ((void*)0)
>   static int *p = NULL;

Are you talking about C or C++ here?  It's already invalid in C++, and
only the definition of NULL would become invalid in C ('static int *p=0;'
would still be ok), which makes me wonder what the int* declaration is
there for.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: 2000/10/18
Raw View
On Wed, 18 Oct 2000 14:30:25 GMT, Fergus Henderson <fjh@cs.mu.OZ.AU> wrot=
e:
[=B7=B7=B7]
> I feel compelled to disagree.  But I'm afraid that I might be
> repeating myself.  If you're reading this on comp.std.c,

Indeed.

> please see the earlier discussion on comp.std.c++.

I'll try to find the time.

[=B7=B7=B7]
> >Now what's with the null pointer constant? For convenience, you want i=
t
> >to be really generic, similar to singleton type. You still want the sa=
me
> >behaviour (i.e. no explicit conversions needed) as all void pointers h=
ad
> >in C all along. Allowing (void *) 0, which is fairly commonly used for
> >NULL in C implementations since pre-ANSI times, was't practical in C++
> >anymore, because an explicit cast would be needed upon assignment to a=
ny
> >pointer type other than void *.
>=20
> That's simply not correct.  If `(void *)0' was a null pointer
> constant, then there would be no need for an explicit cast when
> assigning it to some other pointer type, just as there is no
> need for an explicit cast when assigning `0' to a pointer type.

To quote Stroustrup from D&E-11.2.3:

   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.
   Also, C++ usage was determined long before there was an ANSI C
   standard, and I do not want to have any critical part of C++ rely on
   a makro (=A718). Consequently, I used plain 0, and that has worked ver=
y
   well over the years.

There's more, but this is the essential paragraph. One can disagree with
this rationale (I'm myself not sure that I completely agree), but this
_is_ the rationale why it is how it is today.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/10/18
Raw View

Gabriel Dos Reis wrote:
>
> Valentin Bonnard <Valentin.Bonnard@free.fr> writes:
>
> [...]
>
> | > If the above code would be legal C, why make
> | > the dispensation for (void *)0
> |
> | Probably to allow C++ to define NULL as (void*)0 instead
> | of the ugly (and not type safe) 0.
>
> That would allow `(void *)0' but would not prohibit `0'.  Thus instead
> of one hack, we will have two hacks for spelling the same thing.
>
> --

Agreed.  If we are going to allow funky sequences such as zeros cast to void*
meaning NULL POINTER CONSTANT, why don't we just define an explicit literal
like "NULL" or "__null" to be the constant.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Sebastian Moleski" <sebmol@gmx.net>
Date: 2000/10/18
Raw View
We have eliminated any references to NULL in our own code. IMO, it's not
right to use a non-keyword to express something as special as a null-pointer
constant. Since the only "built-in" way of expressing a null-pointer
constant is 0, we just stuck to it. In that regard, Pascal's nil keyword is
much better as it encapsulates two details: it's a value for a non-defined
pointer, and it's only compatible to pointer types.

sm


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: joerg.barfurth@attglobal.net (Joerg Barfurth)
Date: 2000/10/19
Raw View
[cc'd as the original article was x-posted]

Niklas Matthies <Team-Rocket@gmx.net> wrote:

> To quote Stroustrup from D&E-11.2.3:
>=20
>    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.
>    [...]

> One can disagree with this rationale

That brings to mind the core of this thread's discussion:

Allowing implicit conversions of *int*s to other pointer types [does]
open a (even more) serious hole in the type system. Currently all null
pointer constants are special cases in this regard.


J=F6rg

--=20
J=F6rg Barfurth                         joerg.barfurth@attglobal.net
-------------- using std::disclaimer; -----------------------------
Download:     StarOffice 5.2 at       http://www.sun.com/staroffice
Participate:  OpenOffice now at       http://www.OpenOffice.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/10/19
Raw View
Ron Natalie <ron@sensor.com> writes:
> Agreed.  If we are going to allow funky sequences such as zeros cast to void*
> meaning NULL POINTER CONSTANT, why don't we just define an explicit literal
> like "NULL" or "__null" to be the constant.

That's easily done by implementations:
    enum { __null=0 };
    #define NULL ((void*)__null) /* or just __null for C++ */
But removing the null pointer constant status of 0 and (void*)0 would
break existing code.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: joerg.barfurth@attglobal.net (Joerg Barfurth)
Date: 2000/10/19
Raw View
Niklas Matthies <Team-Rocket@gmx.net> wrote:

> [Still crossposted since it concerns both languages.]
[fup2 set again]


> Valentin Bonnard <Valentin.Bonnard@free.fr> wrote:
> > The problem with allowing only ``integer constant expressions=20
> > with the value 0'' as null pointer constants is that the=20
> > following wouldn't be valid:
> >=20
> >   #define NULL ((void*)0)
> >   static int *p =3D NULL;
> >=20
> > which is, to say the least, annoying (and reminds me why=20
> > C isn't my favorite language).
>=20
> It's C++ that allows only ``integer constant expressions with the value
> 0'' as null pointer constants and makes the above code invalid in C++.
> If you find this annoying, then you should blame C++, not C.

As others have missed Valentin's point as well, I'll elaborate:

It's C that allows initializing values of static storage duration with
constant expressions only. Any null pointer constant (NPC) qualifies,
other expressions that evaluate to a null pointer value do not.

So the following (which elides the issue of what C++ allows for NULL)=20

   #define NOTHING ((void*)0)
   static int *p =3D NOTHING;

- is legal C (at least) since C90

- weren't legal C, if only "integer constant expressions with the
  value 0" were allowed as null pointer constants=20
  (as is the case in C++)

- is not legal C++ (but for different reasons)

HTH, J=F6rg

--=20
J=F6rg Barfurth                         joerg.barfurth@attglobal.net
-------------- using std::disclaimer; -----------------------------
Download:     StarOffice 5.2 at       http://www.sun.com/staroffice
Participate:  OpenOffice now at       http://www.OpenOffice.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: 2000/10/20
Raw View
On Sun, 15 Oct 2000 03:38:14 GMT, kanze@gabi-soft.de <kanze@gabi-soft.de>=
 wrote:
> wmm@fastdial.net writes:
[=B7=B7=B7]
> |>  1) The acceptance of "(void*)0" as a null pointer constant
> |>  is consistent with, not an exception to, C's rules for
> |>  pointer compatibility.
>=20
> No, because C's rules don't have anything to do with pointer
> compatibility.  A null pointer is a special case, and although
> (void*)0 may look like casting an integral 0 to void*, it is *not* a
> normal cast -- the special properties of a null pointer must be
> respected.

It is in fact a "normal cast". C defines null pointer constants by the
following sentence [C99:6.3.2.3p3s1]:

   An integer constant expression with the value 0, or such an
   expression cast to type void *, is called a null pointer constant.

Of course such an expression has then special properties, but the cast
inside is a normal one. Furthermore, because of [C99:6.3.2.3p3s2-p4]

   If a null pointer constant is converted to a pointer type, the
   resulting pointer, called a null pointer, is guaranteed to compare
   unequal to a pointer to any object or function.=20

   Conversion of a null pointer to another pointer type yields a null
   pointer of that type. Any two null pointers shall compare equal.

the expression `(void *) 0' is not only a null pointer constant, but at
the same time a null pointer (because it's the null pointer constant `0'
converted to a pointer type), which `0' by itself is not.

The only effect of `(void *) 0' being a null pointer constant in C
(unless I overlooked something) is
(1) that it is allowed to be the expansion of the NULL macro and
(2) that an expression like

   ( expr ? (void *) 0 : (char *) something )

has type `char *' and not type `void *', because there is a special case
made for null pointer constants as second or third operand to the ?:
operator.

> The reason it [void * 0] does work in C is because the standard says
> it works.

Not quite. If the C standard didn't make `(void *) 0' a null pointer
constant, the only real difference would be for the ?: operator, as
explained above. In all other cases where the C standard makes specific
provisions for null pointer constants, a constant expression with type
void * (which `(void *) <any integer constant expression>' is) would
behave the same.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: 2000/10/20
Raw View
On Sun, 15 Oct 2000 00:49:09 GMT, kanze@gabi-soft.de <kanze@gabi-soft.de>=
 wrote:
[=B7=B7=B7]
> The fact that C allows void*->T*, and C++ doesn't, is irrelevant to the
> discussion, because in both C and C++, null pointer constants are
> special beasts, with special rules.  (In practice, C compilers which
> actually define NULL as (void*)0 are pretty much the exception.  Of
> course, in this case, the one or two exceptions -- Microsoft and
> Borland, do happen to be widespread.)

Gcc does, too. (Actually it defines NULL as "((void *)0)".) So if we
have Microsoft, Borland and gcc, I believe that's already pretty much
widespread.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/10/20
Raw View

Paul Jarc wrote:
>
> Ron Natalie <ron@sensor.com> writes:
> > Agreed.  If we are going to allow funky sequences such as zeros cast to void*
> > meaning NULL POINTER CONSTANT, why don't we just define an explicit literal
> > like "NULL" or "__null" to be the constant.
>
> That's easily done by implementations:
>     enum { __null=0 };

NOPE, that's no better than before __null as an enum identifier is still
implicitly convertable to INT.  That's what we're trying to get away from.
Might as well just use 0.

>     #define NULL ((void*)__null) /* or just __null for C++ */
> But removing the null pointer constant status of 0 and (void*)0 would
> break existing code.

Which unforutnately, is the main arguemnt for not changing it.  The fact
that zero made a good invalid pointer value is purely historical.  The idea
was that you just avoid placing things at location zero (not a probelm in
the origianl C implementations where there were instructions down there, but
easily fixed by just skiping the first few bytes of dataspace in split I-D
modes).  God save us from the second mistake, some joker puting a zero at
location zero.  The zero guaranteed to be converted to an appropriate null
value is "cutsie" and the standards committees have gone to great lengths
to write special verbage to propagate a kludge that should have never made
it out of the earliest implementations of the compiler.

It's the same as the braindamaged array behavior.  Should have been fixed
at the time structs were fixed (to support unique member names and assigment/
passing).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/10/20
Raw View
Ron Natalie <ron@sensor.com> writes:
> Paul Jarc wrote:
> >     enum { __null=0 };
>
> NOPE, that's no better than before __null as an enum identifier is still
> implicitly convertable to INT.

So the implementation must still translate the program, but it can
issue a warning whenever this identifier is used in a non-pointer
context, which is all you need when you're worried about misusing it
by accident.  Remember that silence is never required.

> The fact that zero made a good invalid pointer value is purely
> historical.

Even more than you think - the historical nature of the statement
doesn't support your case any more than the statement itself supports
the case of keeping 0 as a null pointer constant.  A null pointer
represented in source code as '0' need not be represented at runtime
as all-bits-zero.  These days, aside from backward compatibility, 0 is
used just for its mnemonic value for a pointer that points to nothing.
It doesn't tell you anything about the bits.


paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: nmm1@cus.cam.ac.uk (Nick Maclaren)
Date: 2000/10/22
Raw View
In article <39F05612.E1707D6@sensor.com>,
Ron Natalie <ron@sensor.com> writes:
|>
|> Which unforutnately, is the main arguemnt for not changing it.  The fact
|> that zero made a good invalid pointer value is purely historical.  The idea
|> was that you just avoid placing things at location zero (not a probelm in
|> the origianl C implementations where there were instructions down there, but
|> easily fixed by just skiping the first few bytes of dataspace in split I-D
|> modes).  God save us from the second mistake, some joker puting a zero at
|> location zero.  ...

A good many systems have taken great care to put a zero at location
zero, because so many programs relied on that without realising it.
That is not a remark about C, incidentally, as the problem and its
kludge predate the widespread use of C.

I have seen several programs that relied on that property, and not
by accident.  One of them was nominally in C, though its previous
ancestry was murkier than that of a stray cat's ....

Yes, I agree that this mess ought to be cleaned up.  But it is a
waste of time trying to get to a strongly typed language starting
from C, and it will merely cause trouble if it is attempted.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email:  nmm1@cam.ac.uk
Tel.:  +44 1223 334761    Fax:  +44 1223 334679

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kanze@gabi-soft.de
Date: 2000/10/22
Raw View
Team-Rocket@gmx.net (Niklas Matthies) writes:

|>  On Tue, 17 Oct 2000 18:16:31 GMT, Valentin Bonnard
|>  <Valentin.Bonnard@free.fr> wrote:
|>  > James Dennett wrote:
|>  [=B7=B7=B7]
|>  > > Suppose C didn't say that (void *)0 was a NPC.  Wouldn't it still=
 be
|>  > > legal (in C) to write

|>  > > struct X *p =3D (void *)0;

|>  > Yes, it would.

|>  > > If the above code would be legal C, why make the dispensation
|>  > > for (void *)0

|>  > Probably to allow C++ to define NULL as (void*)0 instead of the
|>  > ugly (and not type safe) 0.

|>  You may be mixing up things here (I'm not sure).

|>  First, C++ is not allowed to define NULL as (void*)0, because that's
|>  not a null pointer constant in C++. Secondly, 0 is not ugly (ok,
|>  YMMV), and the missing "type safety", or rather type specificness,
|>  is the very reason why (void *) 0 is not a null pointer constant in
|>  C++ (as opposed to in C).

|>  In C, void * is a generic pointer type that can be assigned to or
|>  from any other data pointer type, i.e. without casting.

In C++, void* is also a generic pointer type.  It is required that you
can convert any object pointer to void* and back again and recover the
initial pointer.  One of the conversions can no longer be implicit, but
that is all.

|>  This is
|>  intentional, and the very reason void * was introduced in the first
|>  place (fomerly, char * was used for this purpose, which needed to be
|>  casted from or to other pointer types). I.e. in C, you write

|>     int *p =3D malloc(500);

|>  without a cast. You don't want a cast there. In C, a cast says to
|>  the human reader "look, I'm doing something special/tricky here" and
|>  to the compiler "I know what I'm doing, don't generate
|>  diagnostics". But conversions from and to void * in C are so
|>  commonplace that it isn't considered something special or
|>  out-of-the-ordinary, therefore having to use a cast wouldn't be
|>  appropriate.

Well, the above is certainly the most frequent case.  Before void*, of
course, most C compilers allowed implicit conversions between all
pointer types, precisely so that the above would not need a cast.

|>  In C++, conversions from and to void * are much less common, and
|>  Stroustrup considered these implicit conversion to be a serious hole
|>  in the type system, and therefore decided to require explicit
|>  conversions in C++. Probably resolving ambiguities with overloading
|>  and such was also an issue.

I think the main reason was that memory allocation was type safe in
C++.  Since that was the main use of the implicit cast, it was dropped.

|>  Now what's with the null pointer constant? For convenience, you want
|>  it to be really generic, similar to singleton type.

That, of course, argues for a special key word.  Which is probably the
best solution anyway.  But it requires a bit of effort -- if f is a
template function, what type should f(NULL) instantiate?

|>  You still want the same
|>  behaviour (i.e. no explicit conversions needed) as all void pointers =
had
|>  in C all along. Allowing (void *) 0, which is fairly commonly used fo=
r
|>  NULL in C implementations since pre-ANSI times, was't practical in C+=
+
|>  anymore, because an explicit cast would be needed upon assignment to =
any
|>  pointer type other than void *.

It was such a common definition for NULL that I never saw it.  All of
the C compilers I ever used defined NULL as 0 or 0L.  This was by far
the most commun definition of NULL when the C standards committee was at
work.  The ((void*)0) was added to support a few MS-DOS compilers (at a
time when C was still pretty exotic on MS-DOS).

The reason that MS-DOS compilers wanted ((void*)0) was linked to the
different memory models.  Technically, passing NULL as a variadic
argument has never worked (but then, before ANSI, variadic arguments
were pretty much implementation dependant anyway).  But historically,
most implementations have defined NULL as the integral type (0 or 0L)
with the same size as a pointer, so that passing NULL as a variadic
argument where a pointer was expected would seem to work.  The MS-DOS
compilers adopted ((void*)0) so that NULL would always have the
appropriate size.  (And so that broken programs would continue to seem
to work.)

|>  Therefore there's the requirement in C++
|>  that a null pointer constant is just an integer constant expression,
|>  without a cast operator.

Non sequitur.  C++ could have just as easily adopted C's rules.

Historically, I suspect that the main reason was first, that C++ was
developed on Unix machines, where NULL was 0 (as it was in the early C
compilers -- I actually think that C++ precedes the void keyword in C).
The primitive compilers probably didn't really give the issue much
thought, and just implemented what the local C compilers implemented
(which was 0 or 0L as a null pointer constant).

|>  And the reason that "0" is a null pointer constant in C comes from
|>  the time when C had't void * yet. A _generic_ null pointer constant
|>  was wanted, and since casting it to _any_ pointer type (like, say,
|>  char *) would make it non-generic (i.e. further casts would be
|>  needed to convert it other types anyway), it made most sense to
|>  leave it at just "0".

Especially as the primitive C compilers also converted implicitly
between int and pointers.  I've seen quite a bit of C code (not
recently, of course) which forgoes declaring malloc, or including the
header in which it was declared.  The implicit declaration, of course,
is int, and since the int converts implicitly to the desired pointer
type...  This breaks, of course, as soon as int's and pointers have
different sizes, but in the early days, I think that there were a lot
of people who weren't really aware of this possibility.

|>  After the introduction of void *, plain "0"
|>  as a null pointer constant in turn wasn't really needed any more,
|>  because now there was void * to express genericness, but of course
|>  it was and is still being used, and many C programmers even think
|>  it's preferable to "(void *) 0" for a couple of reasons.

About the same time void was introduced, or maybe even before, it was
realized that a null pointer didn't have to have the same bit pattern as
an integer 0.  And *that* is the important point about the null pointer
constant.  Whatever and however the null pointer constant is spelled, it
requires compiler magic.

|>  [I am not entirely sure with all that historical stuff, but that's
|>  how I came to understand it. Maybe Dennis Ritchie can shed more
|>  light.]

|>  [=B7=B7=B7]
|>  > The problem with allowing only ``integer constant expressions=20
|>  > with the value 0'' as null pointer constants is that the=20
|>  > following wouldn't be valid:

|>  >   #define NULL ((void*)0)
|>  >   static int *p =3D NULL;

|>  > which is, to say the least, annoying (and reminds me why=20
|>  > C isn't my favorite language).

|>  It's C++ that allows only ``integer constant expressions with the
|>  value 0'' as null pointer constants and makes the above code invalid
|>  in C++.  If you find this annoying, then you should blame C++, not
|>  C.

Actually, the above code is undefined behavior in both languages, since
you aren't allowed to define a macro named NULL.  An implementation
cannot define NULL like this in C++ because the standard says it
cannot.  A C compiler can define NULL like this, because the C standard
says it can.  In the end, it's as simple as that.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kanze@gabi-soft.de
Date: 2000/10/22
Raw View
Team-Rocket@gmx.net (Niklas Matthies) writes:

|>  To quote Stroustrup from D&E-11.2.3:

|>     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.
|>     Also, C++ usage was determined long before there was an ANSI C
|>     standard, and I do not want to have any critical part of C++ rely =
on
|>     a makro (=A718). Consequently, I used plain 0, and that has worked=
 very
|>     well over the years.

The quoted text is a justification of an existing situation, not an
explination of how it came about (except for the bit about Bjarne's
using plain 0).  In fact, of course, the special case is there,
regardless of how you spell a null pointer constant.  A null pointer
constant converts implicitly to any type of pointer.  And there is
otherwise *no* type in C++ which converts implicitly to any type of
pointer.  A null pointer constant is a special case, any way you look at
it.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kanze@gabi-soft.de
Date: 2000/10/22
Raw View
"Balog Pal" <pasa@lib.hu> writes:

|>  But now is not then. With the way C++ is and was tons of code use
|>  plain 0, and not NULL or some other replacement, so stopping the
|>  integer 0 from work as npc would break almost all programs out
|>  there. So I'm sure that will never change, at least not in the next
|>  10 years.

I think that this is one point on which everyone is agreed.  There is no
way, today, that we can change it so that 0 is not a legal null pointer
constant.

What we can do is define a new type of null pointer constant (either
__null, or (void*)0, or whatever), in addition to 0, and require that
NULL be defined as this new type.  Programs which use 0 will continue to
work as before; programs which use NULL only as a pointer will get
additional type protection, and programs which use NULL as an int will
break.  IMHO, we can afford to break the latter.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Dennett <james@evtechnology.com>
Date: 2000/10/13
Raw View
rado42 wrote:

> In article <39da7d7f$1_1@news.nwlink.com>,
>   "Gary Hinger" <garyh@zipperint.com> wrote:
> > Is it 0, ((void*)0), undefined, or something else?
> >
> > Thanks.
> >
> > ---
>
> .. And does does anybody know what is the was the reason that NULL is
> not ((void*) 0) (or something similar, which is *NOT* integral
> constant)?
>
> This would prevent misleading constructs like e.g.:
>
> int* p = 0;
> int x = NULL;
>
> Both are legal, and both seem to ask for trouble.
>
> It looks to me that the desire of having 'uniform initializer'
> (e.g. see pure virtuals syntax) was the reason. I personally
> would prefer distinctive keywords for null pointers and pure
> virtual functions, and not just using '0'.
>
> Farther, is 'int* p = 0' garantied to compile? What does the
> standard say?
>
> Radoslav Getov

int * p = 0 is guaranteed to compile.  0 is a null pointer constant.  The phrase "null pointer constant" is misleading, as it is not a pointer at all.  0 can be converted to a null pointer of any type, including (int *).

int a = NULL is also guaranteed to compile, for any Standard-conforming definition of NULL.  NULL "evaluates to" 0, according to the Standard, so this is an odd way of writing int a(0).  NULL is required to have integral type, and there is a conversion
between any two integral types.

Both of the above statements are obviously Bad Things.  Nobody (I hope) would claim it to be good form to use NULL as another way of writing 0, and few (I hope) think that assigning a literal 0 to pointers is desirable.  The weight of code which uses 0
when it means NULL, however, means that it's a problem to disallow this practice.

gcc "does the right thing" and issues warnings if NULL is used as an integer.  I don't recall if it warns for int *p = 0.

-- James Dennett <jdennett@acm.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Scott Condit" <scottc@h2g2.com>
Date: 2000/10/13
Raw View
"Ron Natalie" <ron@sensor.com> wrote in message
news:39E60846.342F983F@sensor.com...
>
>
> Scott Condit wrote:
>
> >
> > A null pointer constant must be an r-value evaluating to 0.
> > The address-of operator can only be applied to an l-value.
> >
> While it is premitted to be an r-value, it is not required to be one.
> It needs only be an integer constant expression evaluating to zero.
> A const int initialized to zero would fit that definition and still
> be an l-value:

I beg to differ- from the standard (4.10 [1]):
"A null pointer constant is an integral constant expression (5.19) rvalue of
integer type..."

As NULL must be a macro and a null-pointer constant, this implies that the
implementation cannot supply a definition of NULL such as that below.

> const int __null = 0;
> #define NULL __null

Although (from foot-note 63, pp73):
"Converting an integral constant expression (5.19) with value zero always
yields a null pointer (4.10) but converting other expressions that happen to
have value 0 need not yield a null pointer."

However, this intimates that one is otherwise free to use (integral
constant) l-values as initializers for null-pointers.

Scott

-----------------------------------------------------------------
Scott Condit
Software Engineer,
H2G2
email: scottc@remove.this.h2g2.com
-----------------------------------------------------------------
Join us at http://www.h2g2.com/
-----------------------------------------------------------------
International Game Developers' Association
http://www.igda.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: wmm@fastdial.net
Date: 2000/10/13
Raw View
In article <8s5oq0$cl7$1@mulga.cs.mu.OZ.AU>,
  fjh@cs.mu.OZ.AU (Fergus Henderson) wrote:
> The idea would be to allow `((void *)0)' as a null pointer constant,
> *just like ANSI/ISO C does*, and then to require NULL to be defined
> as `((void *)0)'.  This was proposed to the C++ comittee.
> Unfortunately they voted against it.  I think the main stated reason
> was that they thought allowing `(void *)0' as a null pointer constant
> was ugly.  I never really understood the decision, and certainly
didn't
> agree with it.

The problem is that it _couldn't_ be done in C++ "just like
ANSI/ISO C does."  In C, "(void*)0" works as a null pointer
constant because a void* is compatible with all other
pointer types.  C++ has more rigorous type safety and a
void* pointer must be explicitly converted to the target
type.

Allowing "(void*)0" as a null pointer constant would either
require adopting the C approach of making void* pointers
universally compatible or making an exception to the type
rules specifically for this particular expression.  I guess
it's accurate to say that the Committee found both of those
choices "ugly."

> But we've had this discussion many times before.  I suggest that
> anyone who is interested in learning about this topic go to DejaNews
> and read the hundreds of messages that have been posted about it in
> this newsgroup, rather than just reposting the same misconceptions
> yet again ;-)

Yes, sorry for my post, but I couldn't help myself. :-)

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: 2000/10/13
Raw View
In article <8s6s9s$cl8$1@nnrp1.deja.com>, wmm@fastdial.net wrote:

> In article <8s5oq0$cl7$1@mulga.cs.mu.OZ.AU>,
>   fjh@cs.mu.OZ.AU (Fergus Henderson) wrote:
> > The idea would be to allow `((void *)0)' as a null pointer constant,
> > *just like ANSI/ISO C does*, and then to require NULL to be defined
> > as `((void *)0)'.  This was proposed to the C++ comittee.
> > Unfortunately they voted against it.  I think the main stated reason
> > was that they thought allowing `(void *)0' as a null pointer constant
> > was ugly.  I never really understood the decision, and certainly
> didn't
> > agree with it.
>
> The problem is that it _couldn't_ be done in C++ "just like
> ANSI/ISO C does."  In C, "(void*)0" works as a null pointer
> constant because a void* is compatible with all other
> pointer types.  C++ has more rigorous type safety and a
> void* pointer must be explicitly converted to the target
> type.

This is completely, absolutely wrong. In C, "(void *) 0" works because
"(void *) 0" is defined as a "null pointer constant". Just like 0 is
defined to be a "null pointer constant". There is absolutely no technical
reason why the same couldn't have been done in C++.

The argument that "C++ has more rigorous type safety and a void* pointer
must be explicitly converted to the target type" is nonsense. If that was
the reason, how could "int* p = 0;" ever be legal? 0 is an int, how come
you can assign it to a pointer?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Niklas Mellin <nimel@my-deja.com>
Date: 2000/10/13
Raw View
In article <39E67BAA.B329EB39@evtechnology.com>,
  James Dennett <james@evtechnology.com> wrote:

[...]

> and few (I hope) think that assigning a literal 0 to pointers is
> desirable.

I do it. Bjarne Stroustrup do it. Really it is mostly a matter of
style and habit.

I use NULL in C. I used to use NULL in C++, until I stumbled across
one of these compilers that defined NULL as (void*)0, and I had to
cast everytime I used NULL. I guess that is fixed almost now, but I
haven't bothered to change back my habits yet.

[...]

> gcc "does the right thing" and issues warnings if NULL is used as an
> integer.  I don't recall if it warns for int *p = 0.

It doesn't and it shouldn't.

/Niklas Mellin



Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Sebastian Moleski" <sebmol@gmx.net>
Date: 2000/10/13
Raw View
AFAIK, an lvalue is always also an rvalue. That means whereever you can put
an rvalue, an lvalue is just as good. Of course, the opposite doesn't hold
true.

sm


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: wmm@fastdial.net
Date: 2000/10/13
Raw View
In article <christian.bau-1310001635010001@christian-
mac.isltd.insignia.com>,
  christian.bau@isltd.insignia.com (Christian Bau) wrote:
> In article <8s6s9s$cl8$1@nnrp1.deja.com>, wmm@fastdial.net wrote:
>
> > The problem is that it _couldn't_ be done in C++ "just like
> > ANSI/ISO C does."  In C, "(void*)0" works as a null pointer
> > constant because a void* is compatible with all other
> > pointer types.  C++ has more rigorous type safety and a
> > void* pointer must be explicitly converted to the target
> > type.
>
> This is completely, absolutely wrong. In C, "(void *) 0" works because
> "(void *) 0" is defined as a "null pointer constant". Just like 0 is
> defined to be a "null pointer constant". There is absolutely no
technical
> reason why the same couldn't have been done in C++.
>
> The argument that "C++ has more rigorous type safety and a void*
pointer
> must be explicitly converted to the target type" is nonsense. If that
was
> the reason, how could "int* p = 0;" ever be legal? 0 is an int, how
come
> you can assign it to a pointer?

In the interests of civil discussion, I think it would be better
to avoid rhetoric like "completely, absolutely wrong" and
"nonsense" in describing others' positions.  Some people with
thinner skins than mine might be offended. :-)

The following facts are indisputable:

1) In C, an expression of type "void*" can be assigned to any
pointer.

2) In C++, as currently constituted, an expression of type
"void*" cannot be assigned to pointers whose type is not
"void*."

3) The type of "(void*)0" is "void*".

4) Some change to the definition of C++ would be required to
permit "(void*)0" to be assignable to non-void* pointers.

Exactly what change would be required, how significant that
change would be, and whether the change is desirable or not
are areas of legitimate difference of opinion.  You're right,
there's "no technical reason it couldn't have been done in
C++" -- I never suggested otherwise -- but there is room for
disagreement about whether it _should_ have been done.

Whether "(void*)0" works in C because of the pointer
compatibility or because of its explicit definition as a
null pointer constant is, I think, not a very fruitful area
of discussion.  Having phrased my comment the way I did was
probably unfortunate.  The two points I had in mind with that
statement were:

1) The acceptance of "(void*)0" as a null pointer constant
is consistent with, not an exception to, C's rules for
pointer compatibility.

2) The reason "(void*)0" _doesn't_ work in C++ is a direct
consequence of the difference between the pointer compatibility
rules of C and C++.

As for the point about integer 0 being incompatible with
pointer types, I completely agree.  Unfortunately, we're
stuck with that because of C compatibility (direct use in the
source, not mediated by the "NULL" preprocessor symbol).
That doesn't mean I have to like "(void*)0" any better,
though.

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/10/14
Raw View
wmm@fastdial.net writes:

>The following facts are indisputable:
>
>1) In C, an expression of type "void*" can be assigned to any
>pointer.
>
>2) In C++, as currently constituted, an expression of type
>"void*" cannot be assigned to pointers whose type is not
>"void*."
>
>3) The type of "(void*)0" is "void*".
>
>4) Some change to the definition of C++ would be required to
>permit "(void*)0" to be assignable to non-void* pointers.

Agreed.

>The two points I had in mind with that statement were:
>
>1) The acceptance of "(void*)0" as a null pointer constant
>is consistent with, not an exception to, C's rules for
>pointer compatibility.

Here I mostly agree.  However, the definition of null pointer constant
in C is quite arbitrary.  For example, `(void *)(void *)0' is NOT a
null pointer constant, even though allowing that would be quite
consistent with C's rules for pointer compatibility.  And there is no
_need_ for C to allow `(void *)0' as a null pointer; the C standard
allows this because this it useful, not because it is necessary.

>2) The reason "(void*)0" _doesn't_ work in C++ is a direct
>consequence of the difference between the pointer compatibility
>rules of C and C++.

Here I must disagree.  The reason that `(void*)0' doesn't work
in C++ is because the definition of null pointer constant
is different in C++.  That in turn may have been done for
consistency with C++'s rules on pointer compatibility,
but if so it's still only an indirect consequence, not a direct one.

Furthermore, the argument that `(void*)0' shouldn't work in C++
for consistency with C++'s rules on pointer compatibility
is a very weak one, IMHO.  The reason for C++'s stricter
rules on pointer compatibility is to ensure type safety,
but allowing `(void*)0' as a null pointer constant poses
no threat to type safety.  In fact it has the converse effect:
it improves type safety, by ensuring that the compiler will
catch things like `int x = NULL' (presuming NULL is suitably
defined, of course).  The consistency argument should therefore
IMHO be strongly outweighed by the two advantages of improved type
safety and better compatibility with C.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kanze@gabi-soft.de
Date: 2000/10/14
Raw View
"Sebastian Moleski" <sebmol@gmx.net> writes:

|>  AFAIK, an lvalue is always also an rvalue. That means whereever you
|>  can put an rvalue, an lvalue is just as good. Of course, the
|>  opposite doesn't hold true.

You're thinking of C (where there are no rvalues).  In C++, an
expression is either an lvalue or an rvalue, and there is an lvalue to
rvalue conversion (implicit, of course).

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Dennett <james@evtechnology.com>
Date: 2000/10/14
Raw View
michael wrote:

> <wmm@fastdial.net> wrote in message news:8s7jdv$125$1@nnrp1.deja.com...
> > As for the point about integer 0 being incompatible with
> > pointer types, I completely agree.
>
> I'm cool with the integer 0 being convertible to a pointer.  After all, zero
> readily converts to bool, to float, to complex.

0 converts to bool(false) because there is a conversion from int to bool, not because there's a special rule for 0.  It's perfectly possible to write "bool my_odd_version_of_true(27)".  I believe that there were those on the C++ Committee who would have
preferred to avoid this implicit conversion from int to bool, but it would have broken too many standard (and ugly) C idioms because conditions are required to be booleans in C++ where they were ints in C.  If C++ were designed without a legacy from C, I
doubt that conversions from int to bool would be included.

There's no analagous conversion from int to (X*), for any type X.  There's a special rule which says that a null pointer constant can be implicitly converted to a null pointer of type (X*).

The following code does not compile (as C++) because the integer 0 is not convertible to a pointer:

int a = 0;
void *p = a;

The following works because b is a null pointer constant:

const int b = 0;
void *p = b;

> Zero is a happy member of so many fields.

Zero is a number.  I'm happy for it to be converted to int, long, float, complex<double>, or any other type which defines addition and has an additive identity.  It's not a boolean ("zero" isn't true or false, and we can't add booleans), and it's not a
pointer (we can't add pointers).

0, on the other hand, and from a purely C/C++ perspective, is defined to be a "null pointer constant".  While this still isn't a pointer, it can be converted to one.  This can be viewed as either elegant re-use of the concept of zero, or an abuse of the
concept of zero.  Those who like strong typing tend to consider the use of 0 as a pointer to be a Bad Thing.

I sometimes wish that there were two modes defined by Standard C++ -- backwards (C-compatible) mode, and sensible (safe) mode.  I dread to think how much compexity this would have added to the standardization process though.  It would be nice to deprecate
implicit conversions to bool at some time in the future, and I'd be for redefining "null pointer constant" at that time to mean something like "__null_pointer_constant", which would be a new reserved word.  Probably more experienced people can think of
better ways to get rid of this overloading of 0.

Unusually, Java got this right.  You can't ever assign any integral expression to a pointer (sorry, "reference"), and the Java version of a null pointer (sorry, "reference") constant is spelt "null" and can't be assigned to integers.  Java also eliminated
implicit conversions to bool.  (The Java type system is far from perfect though: no const, (compile-time) unsafe array conversions, lack of covariant return types, no genericity suppor, I could go on.)  My point is just that Java avoids two of the
problems which C++ inherited from C, and it would be nice for C++ to do the same in the future.

-- James Dennett <jdennett@acm.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "michael" <serrano@ozemail.com.au>
Date: Sun, 15 Oct 2000 00:46:32 GMT
Raw View
> few (I hope) think that assigning a literal 0 to pointers is desirable.
while NULL is not a keyword, I'm one of the few.

<wmm@fastdial.net> wrote in message news:8s7jdv$125$1@nnrp1.deja.com...
> As for the point about integer 0 being incompatible with
> pointer types, I completely agree.

I'm cool with the integer 0 being convertible to a pointer.  After all, zero
readily converts to bool, to float, to complex.
Zero is a happy member of so many fields.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Sun, 15 Oct 2000 00:46:01 GMT
Raw View
"Marco Dalla Gasperina" <marcodg@home.com> writes:

|>  What about:

|>  const int* x =3D &NULL;

|>  I don't recall the specific disallowment of taking the address of
|>  NULL... but it is a pretty cooky concept...

NULL is not required to be an lvalue, and generally isn't.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Sun, 15 Oct 2000 00:47:31 GMT
Raw View
Niklas Mellin <nimel@my-deja.com> writes:

|>  In article <39E67BAA.B329EB39@evtechnology.com>,
|>    James Dennett <james@evtechnology.com> wrote:

|>  [...]

|>  > and few (I hope) think that assigning a literal 0 to pointers is
|>  > desirable.

|>  I do it. Bjarne Stroustrup do it. Really it is mostly a matter of
|>  style and habit.

Doing it, and thinking it is desirable, are two different things.  Given
the current rules of function overloading, and the requirements on the
definition of NULL, I can fully understand why some people prefer to
write 0 instead of NULL, as the lesser of two evils.

|>  I use NULL in C. I used to use NULL in C++, until I stumbled across
|>  one of these compilers that defined NULL as (void*)0, and I had to
|>  cast everytime I used NULL. I guess that is fixed almost now, but I
|>  haven't bothered to change back my habits yet.

This is one of the principal reasons people started using NULL in C++.
I haven't had a problem with NULL, however, in the last ten years.

One of the reasons people continue to prefer 0 is that its effect in
function overloading is more obvious.  The fact that f(NULL) will prefer
f(int) over f(T*) is surprising, to say the least.  While I prefer to
avoid the problem by not overloading between integral and pointer types,
I can fully understand the other point of view.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Sun, 15 Oct 2000 00:49:09 GMT
Raw View
wmm@fastdial.net writes:

|>  In article <8s5oq0$cl7$1@mulga.cs.mu.OZ.AU>,
|>    fjh@cs.mu.OZ.AU (Fergus Henderson) wrote:

|>  > The idea would be to allow `((void *)0)' as a null pointer
|>  > constant, *just like ANSI/ISO C does*, and then to require NULL to
|>  > be defined as `((void *)0)'.  This was proposed to the C++
|>  > comittee.  Unfortunately they voted against it.  I think the main
|>  > stated reason was that they thought allowing `(void *)0' as a null
|>  > pointer constant was ugly.  I never really understood the
|>  > decision, and certainly didn't agree with it.

|>  The problem is that it _couldn't_ be done in C++ "just like ANSI/ISO
|>  C does."  In C, "(void*)0" works as a null pointer constant because
|>  a void* is compatible with all other pointer types.  C++ has more
|>  rigorous type safety and a void* pointer must be explicitly
|>  converted to the target type.

In C, "(void*)0" works as a null pointer constant because the standard
says it does.  In both C and C++, 0 works as a null pointer constant
because (and only because) the standard says so.  It makes a special
rule for an "integral constant expression evaluating to 0", or in C, for
the same type of expression cast to void*.  Even in C, just casting an
integer which happens to contain 0 won't result in a null pointer
constant.

The fact that C allows void*->T*, and C++ doesn't, is irrelevant to the
discussion, because in both C and C++, null pointer constants are
special beasts, with special rules.  (In practice, C compilers which
actually define NULL as (void*)0 are pretty much the exception.  Of
course, in this case, the one or two exceptions -- Microsoft and
Borland, do happen to be widespread.)

|>  Allowing "(void*)0" as a null pointer constant would either
|>  require adopting the C approach of making void* pointers
|>  universally compatible or making an exception to the type
|>  rules specifically for this particular expression.  I guess
|>  it's accurate to say that the Committee found both of those
|>  choices "ugly."

You mean to say they found it less ugly to make an exception to the type
rules specifically for the integer 0?

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Marco Dalla Gasperina" <marcodg@home.com>
Date: 2000/10/11
Raw View
"Jim Hyslop" <jim.hyslop@leitch.com> wrote in message
news:8s1vms$bh0$1@nnrp1.deja.com...
> Assuming that the compiler defines __null to be the equivalent of:
>
> const int __null=0;
>
> what would make that non-conforming? It's still an integral constant
> expression evaluating to zero.

Assuming

#define NULL __null

What about:

const int* x = &NULL;

I don't recall the specific disallowment of taking the address of
NULL... but it is a pretty cooky concept...

marco


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Scott Condit" <scottc@h2g2.com>
Date: 2000/10/12
Raw View
"Marco Dalla Gasperina" <marcodg@home.com> wrote in message
news:rg1F5.166314$Ur3.2479796@news1.sttls1.wa.home.com...
>
> "Jim Hyslop" <jim.hyslop@leitch.com> wrote in message
> news:8s1vms$bh0$1@nnrp1.deja.com...
> > Assuming that the compiler defines __null to be the equivalent of:
> >
> > const int __null=0;
> >
> > what would make that non-conforming? It's still an integral constant
> > expression evaluating to zero.
>
> Assuming
>
> #define NULL __null
>
> What about:
>
> const int* x = &NULL;
>
> I don't recall the specific disallowment of taking the address of
> NULL... but it is a pretty cooky concept...
>
> marco

A null pointer constant must be an r-value evaluating to 0.
The address-of operator can only be applied to an l-value.

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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/10/12
Raw View

Scott Condit wrote:

>
> A null pointer constant must be an r-value evaluating to 0.
> The address-of operator can only be applied to an l-value.
>
While it is premitted to be an r-value, it is not required to be one.
It needs only be an integer constant expression evaluating to zero.
A const int initialized to zero would fit that definition and still
be an l-value:
 const int __null = 0;
#define NULL __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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: rado42 <rado42@my-deja.com>
Date: 2000/10/12
Raw View
In article <39da7d7f$1_1@news.nwlink.com>,
  "Gary Hinger" <garyh@zipperint.com> wrote:
> Is it 0, ((void*)0), undefined, or something else?
>
> Thanks.
>
> ---

.. And does does anybody know what is the was the reason that NULL is
not ((void*) 0) (or something similar, which is *NOT* integral
constant)?

This would prevent misleading constructs like e.g.:

int* p = 0;
int x = NULL;

Both are legal, and both seem to ask for trouble.

It looks to me that the desire of having 'uniform initializer'
(e.g. see pure virtuals syntax) was the reason. I personally
would prefer distinctive keywords for null pointers and pure
virtual functions, and not just using '0'.

Farther, is 'int* p = 0' garantied to compile? What does the
standard say?


Radoslav Getov


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 2000/10/12
Raw View
In article <8s51oc$ucg$1@nnrp1.deja.com>,
  rado42 <rado42@my-deja.com> wrote:
> In article <39da7d7f$1_1@news.nwlink.com>,
>   "Gary Hinger" <garyh@zipperint.com> wrote:
> > Is it 0, ((void*)0), undefined, or something else?
> >
> > Thanks.
> >
> > ---
>
> .. And does does anybody know what is the was the reason that NULL is
> not ((void*) 0) (or something similar, which is *NOT* integral
> constant)?
Because this code would fail to compile:

class T;
T *t = NULL;


>
> This would prevent misleading constructs like e.g.:
>
> int* p = 0;
> int x = NULL;
>
> Both are legal, and both seem to ask for trouble.
>
> It looks to me that the desire of having 'uniform initializer'
> (e.g. see pure virtuals syntax) was the reason. I personally
> would prefer distinctive keywords for null pointers and pure
> virtual functions, and not just using '0'.
>
> Farther, is 'int* p = 0' garantied to compile? What does the
> standard say?
Yes, it must compile on a conforming compiler.

Clause 4.10 states: "1. A null pointer constant is an integral constant
expression 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...."

(Side bar: Nothing is ever guaranteed. The standard places requirements
on conforming compilers, but makes no guarantees.)

--
Jim
This message was posted using plain text only.  Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: Fri, 13 Oct 2000 05:01:43 GMT
Raw View
Jim Hyslop <jim.hyslop@leitch.com> writes:

>rado42 <rado42@my-deja.com> wrote:
>> "Gary Hinger" <garyh@zipperint.com> wrote:
>> > Is it 0, ((void*)0), undefined, or something else?
>>
>> .. And does does anybody know what is the was the reason that NULL is
>> not ((void*) 0) (or something similar, which is *NOT* integral
>> constant)?
>
>Because this code would fail to compile:
>
>class T;
>T *t = NULL;

No, no, that's completely wrong.  You've entirely missed the point.
The idea would be to allow `((void *)0)' as a null pointer constant,
*just like ANSI/ISO C does*, and then to require NULL to be defined
as `((void *)0)'.  This was proposed to the C++ comittee.
Unfortunately they voted against it.  I think the main stated reason
was that they thought allowing `(void *)0' as a null pointer constant
was ugly.  I never really understood the decision, and certainly didn't
agree with it.

But we've had this discussion many times before.  I suggest that
anyone who is interested in learning about this topic go to DejaNews
and read the hundreds of messages that have been posted about it in
this newsgroup, rather than just reposting the same misconceptions
yet again ;-)

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: 2000/10/10
Raw View
James Dennett wrote:
> C++ requires only that NULL is a macro expanding to a null pointer
> constant.  That is, a constant expression (as defined in the Standard)
> of integral type (also defined in the Standard) which compares equal
> to 0.
> [...]
> One post (to this group or comp.lang.c++.moderated, I don't recall
> which) pointed out that the Standard appears to allow things like
>
> namespace __implementation_private_namespace {
>   const int __null_pointer_contant = 0;
> }
> #define NULL \
>   (__implementation_private_namespace::__null_pointer_contant)
>
> which could interact in unpleasant ways with "Koenig" name lookup.
> Naturally no sane implementor would do this, but it does help to
> illustrate what the Standard does _not_ define about NULL.

If the expression acts like an integral constant expression that
evaluates to zero in all cases, then it's legal as a value for NULL.
It appears that the example given above meets this requirement.

Also, while it's technically not conforming, an implementation could
use a special reserved word or identifier as "null pointer constant",
e.g., defining NULL to something like '__null', which is a special
name known to the compiler.  (I believe some of the GCC variants
actually do this.)

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 2000/10/11
Raw View
In article <39E3544E.739519D1@tribble.com>,
  David R Tribble <david@tribble.com> wrote:
[snip]
> Also, while it's technically not conforming, an implementation could
> use a special reserved word or identifier as "null pointer constant",
> e.g., defining NULL to something like '__null', which is a special
> name known to the compiler.  (I believe some of the GCC variants
> actually do this.)
Assuming that the compiler defines __null to be the equivalent of:

const int __null=0;

what would make that non-conforming? It's still an integral constant
expression evaluating to zero.

--
Jim
This message was posted using plain text only.  Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/10/11
Raw View

Jim Hyslop wrote:
>

> Assuming that the compiler defines __null to be the equivalent of:
>
> const int __null=0;
>
> what would make that non-conforming? It's still an integral constant
> expression evaluating to zero.
>
I think the issue was if NULL were to be some magic cookie that behaved
like a null pointer constant when compared/assigned to pointers, but did
not behave like an integer when used otherwise.

#define NULL __internal_null_pointer_constant__

 T* x = NULL; // OK
 if(x == NULL) ...  // OK

 int i = NULL;  // FAIL:  Can't convert __internal_null_pointer_constant__ to int.

The standard N.P.C. would have the last test succeed.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kanze@gabi-soft.de
Date: 2000/10/08
Raw View
James Dennett <james@evtechnology.com> writes:

|>  C++ requires only that NULL is a macro expanding to a null pointer
|>  constant.  That is, a constant expression (as defined in the
|>  Standard) of integral type (also defined in the Standard) which
|>  compares equal to 0.  From 18.1/4: "The macro NULL is an
|>  implementation-defined C++ null pointer constant in this
|>  International Standard (4.10)."  4.10 defines the term "null pointer
|>  constant".

|>  Legal defintions for NULL in C++ include 0, 0L, (1-1) etc.

Since you're talking about making this more or less a FAQ, there is an
additional requirement, so obvious that we normally never think about
it: the definition of NULL (like the definition of all constants which
are macros) must be either a single token or parenthesed: '(1-1)' is
legal, but '1-1' isn't.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Gary Hinger" <garyh@zipperint.com>
Date: Wed, 4 Oct 2000 06:25:47 GMT
Raw View
Is it 0, ((void*)0), undefined, or something else?

Thanks.



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Dennett <james@evtechnology.com>
Date: 2000/10/04
Raw View
Gary Hinger wrote:

> Is it 0, ((void*)0), undefined, or something else?
>
> Thanks.

This is something of a FAQ, but in the hope that more people might search the archives before asking again, I'll try to explain.

C++ requires only that NULL is a macro expanding to a null pointer constant.  That is, a constant expression (as defined in the Standard) of integral type (also defined in the Standard) which compares equal to 0.  From 18.1/4: "The macro NULL is an
implementation-defined C++ null pointer constant in this International Standard (4.10)."  4.10 defines the term "null pointer constant".

Legal defintions for NULL in C++ include 0, 0L, (1-1) etc.

(void *)0 is not a legal definition for NULL in C++; it does not have integral type.

(Footnote 180 on page 327 of my copy of the Standard states: "Possible definitions include 0 and 0L, but not (void*)0").

One post (to this group or comp.lang.c++.moderated, I don't recall which) pointed out that the Standard appears to allow things like

namespace __implementation_private_namespace {
  const int __null_pointer_contant = 0;
}
#define NULL (__implementation_private_namespace::__null_pointer_contant)

which could interact in unpleasant ways with "Koenig" name lookup.  Naturally no sane implementor would do this, but it does help to illustrate what the Standard does _not_ define about NULL.

-- James Dennett <jdennett@acm.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]