Topic: Adding a pointer literal to C++
Author: Allan_W@my-dejanews.com (Allan W)
Date: Mon, 16 Sep 2002 15:55:59 CST Raw View
Attila.Feher@lmf.ericsson.se (Attila Feher) wrote
> Allan W wrote:
[SNIP]
> > What's required, then, is a way to specify the type of null pointer
> > we wish to use. Imagine some hypothetical "nil" function which
> > specifies the pointer type:
> > namespace std {
> > template<class T>T*nil() { return 0; }
> > }
> > //...
> > f(nil<int>());
> > But we already have this, it's called a cast.
> > f((int*)0);
> > This also works when there are f() overloads that take non-pointers,
> > such as f(int) and f(char).
>
> Oooooo. Nope. No cast, thank you.
I already agreed... (below)
[snip]
> > ...But casts are evil. I'd like to be able to specify
> > an int*null as opposed to a char*null, without using a cast. Currently
> > we can't do this, except with functions such as I've presented above.
>
> I guess that the nil stuff is a good "workaround" it would only be nicer
> if we wouldn't need the () of the construction.
How 'bout this?
// Header "null.h"
void* const NULLvoid = 0;
char* const NULLchar = 0;
char* const NULLint = 0;
char* const NULLdouble = 0;
// ... and so on...
f(NULLchar); // Calls f(char*)
Yes, you would have to extend "null.h" for most programs, especially
if you sometimes need null pointers to user-defined class types -- but
those extensions would be one-time and obvious (save perhaps for the
need for forward declarations). Meanwhile, this construct is 100% legal
today (without language extensions) and completely disambiguates any
call of this type. It avoids using any casts. The unusual capitalization
strategy makes name collisions highly unlikely, and yet it is highly
readable due to an easy-to-remember name which makes both the data
type and value extremely clear (reminiscent of the C name 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Allan_W@my-dejanews.com (Allan W)
Date: Wed, 11 Sep 2002 23:33:56 +0000 (UTC) Raw View
Attila.Feher@lmf.ericsson.se (Attila Feher) wrote
> If you could actually tell the _why_ do you think the topic is mute -
> and I mean technical arguments, the above seems rather political - that
> would help us to:
>
> a.) understand it isn't worth touching
>
> b.) get a step closer to a solution by seeing what is/was the problem
> with the earlier proposals failing acceptance
Okay, I'll bite.
The OP wrote
void f(int);
void f(char);
void f(int*);
//...
f(NULL); // Ambiguous
The obvious conclusion is to define NULL in such a way that it can
match int* but not int or char. Under the current rules of C++, there
is no such expression, but under the rules of C, the expression
"(void*)0" works well. Therefore, the obvious change is to allow void*
to be silently converted to any other pointer type, just as C allows.
Another reasonably-obvious solution would extend the standard library:
namespace std {
struct nil {
template<class T>operator T*() const { return (T*)0; }
} const NULL;
}
This replacement for NULL would actually be an object, but it
could be converted into any type of pointer object. Add this to the
code above, and we no longer try to call f(int) or f(char), so the
problem seems to be solved.
But the general problem goes further than the OP stated:
void f(int);
void f(char);
void f(int*);
void f(double*);
void f(void*);
void f(char*);
//...
f(NULL); // Which one?
Whether NULL is a void* or an instance of nil, it can still convert
into any one of the pointer types. You can't have it both ways --
either it converts into any pointer type, or it doesn't. Either way,
it doesn't resolve this generalized form of the problem.
Furthermore, we simply CANNOT stop converting constant-expression 0
into a null pointer -- we would break the majority of C++ programs
that exist today.
Since C doesn't have overloaded functions, this problem will never
come up in C -- and the C "solution" isn't going to solve the problem
in C++.
What's required, then, is a way to specify the type of null pointer
we wish to use. Imagine some hypothetical "nil" function which
specifies the pointer type:
namespace std {
template<class T>T*nil() { return 0; }
}
//...
f(nil<int>());
But we already have this, it's called a cast.
f((int*)0);
This also works when there are f() overloads that take non-pointers,
such as f(int) and f(char).
If the language already lets me disambiguate null types, why do we
need to do anything at all?
We don't, really. But casts are evil. I'd like to be able to specify
an int*null as opposed to a char*null, without using a cast. Currently
we can't do this, except with functions such as I've presented above.
I see this as a small point, though.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Sep 2002 23:34:07 +0000 (UTC) Raw View
thp@cs.ucr.edu wrote:
> Now Java is taking mindshare from C++.
What's wrong with that? Aren't we tired yet of these
silly language wars? Every language has its strengths
and weaknesses, its hard parts and its easy parts.
Changes to C++ should be in the direction of making it
more like C++, not more like another language. Then let
people choose whatever language they want. If they all
depart the C++ camp, so be it. I'll go hang out in the
Java groups (or more likely the Ada group, where most
everyone already left).
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net ("James Russell Kuyper Jr.")
Date: Thu, 12 Sep 2002 03:46:50 +0000 (UTC) Raw View
Gennaro Prota wrote:
>
> On Tue, 10 Sep 2002 21:32:49 +0000 (UTC), hyrosen@mail.com (Hyman
> Rosen) wrote:
....
> >0 was a null-pointer constant in C before void was even a
> >keyword in that language.
>
> Are you kidding. C++ was standardized 8 years later than C90, which
> has void and allows NULL to be defined as (void*)0. C++ explicitly
C is a lot older than C90, just as C++ is a lot older than C++98. And
pre-standard C did have null-pointer constants, long before any version
of C had 'void'.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Attila.Feher@lmf.ericsson.se (Attila Feher)
Date: Thu, 12 Sep 2002 17:12:34 +0000 (UTC) Raw View
Hyman Rosen wrote:
>
> Attila Feher wrote:
> > If you could actually tell the _why_ do you think the topic is mute -
>
> "moot"
THX. I will remember it from foot. :-) Well, this happens when you
learn English from Cartoon Network. ;-)
> > and I mean technical arguments, the above seems rather political
>
> You couldn't do away with using 0 as a null pointer constant
> because of backward compatibility, so at best this would be a
> feature applicable only to new code.
I don't get you. If this pointer literal thing is prepared on a way
that it does not replace NULL but introduces a new, non-conflicting
element why would it break your code?
> This feature, as all others,
> must be carefully specified, with attention as to how it interacts
> with other aspects of the language.
Sure. As any other proposal.
> The end result of the chunk of
> work is to paper over a minor fault in the language that probably
> never, or hardly ever, shows up in real-world code, and if it did
> is easily taken care of.
I have to be very careful how to word this... But I hardly believ that
you have seen _every_ real world application. I sometimes wonder how
little I must know, especially when I see people in csc++ telling that
this and that is never and rarely used/seen in production code... And
it is especially surprising when I have it all around the one I see in
front of me... I am not talking about this here.
And I must say (with all respect) that these so far were opinions,
yours. Not technical arguments. :-(
> There are also roll-your-own solutions, along the lines of
>
> static struct{template<class T>operator T*(){return 0;}}null;
>
> So you can't do away with the old form, the new form doesn't
> matter, and you can do it yourself anyway. These are the
> classic reasons for not adopting a new feature.
Does this have _exactly_ the _same_ effect and behavior than the pointer
literal would have? If the answer is yes, I've got your point and fully
agree. If not, then it is rather an excuse than an argument. I
remember if there were some drawbacks... My memory again.
Attila
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Attila.Feher@lmf.ericsson.se (Attila Feher)
Date: Thu, 12 Sep 2002 17:14:05 +0000 (UTC) Raw View
Allan W wrote:
[SNIP]
> Another reasonably-obvious solution would extend the standard library:
> namespace std {
> struct nil {
> template<class T>operator T*() const { return (T*)0; }
> } const NULL;
> }
> This replacement for NULL would actually be an object, but it
> could be converted into any type of pointer object. Add this to the
> code above, and we no longer try to call f(int) or f(char), so the
> problem seems to be solved.
I like the above one. Does it really behave exactly as we wish it to?
> But the general problem goes further than the OP stated:
> void f(int);
> void f(char);
> void f(int*);
> void f(double*);
> void f(void*);
> void f(char*);
>
> //...
> f(NULL); // Which one?
> Whether NULL is a void* or an instance of nil, it can still convert
> into any one of the pointer types.
Certainly. I was rather interested in pointer literals from the
original proposal, not only its possible use for NIL (or whatever).
> You can't have it both ways --
> either it converts into any pointer type, or it doesn't. Either way,
> it doesn't resolve this generalized form of the problem.
I must say it isn't the same problem. I mean the original one had
ptr<->int ambiguity. This one has ptr<->ptr, wich is not the same. It
is another problem, for which the proposed solution isn't good, but the
nil<char>() is a cool one - thanx to Scott Meyers!
> Furthermore, we simply CANNOT stop converting constant-expression 0
> into a null pointer -- we would break the majority of C++ programs
> that exist today.
Here I agree 100% with no doubt.
> Since C doesn't have overloaded functions, this problem will never
> come up in C -- and the C "solution" isn't going to solve the problem
> in C++.
Yep.
> What's required, then, is a way to specify the type of null pointer
> we wish to use. Imagine some hypothetical "nil" function which
> specifies the pointer type:
> namespace std {
> template<class T>T*nil() { return 0; }
> }
> //...
> f(nil<int>());
> But we already have this, it's called a cast.
> f((int*)0);
> This also works when there are f() overloads that take non-pointers,
> such as f(int) and f(char).
Oooooo. Nope. No cast, thank you. I have read recent studies that
playing with casts can cause serious trouble in afterlife and
reincarnations. I would rather stick with the nil one. _And_ if you
_must_ cast please use the new style. It is so ugly that it is nice.
> If the language already lets me disambiguate null types, why do we
> need to do anything at all?
I did not say we do need. :-) I just objected saying: we have
discussed this and decided not to - as a technical answer.
> We don't, really. But casts are evil. I'd like to be able to specify
> an int*null as opposed to a char*null, without using a cast. Currently
> we can't do this, except with functions such as I've presented above.
I guess that the nil stuff is a good "workaround" it would only be nicer
if we wouldn't need the () of the construction.
> I see this as a small point, though.
I am a kinda guy, who looks at the technical part (if understands it :-)
and at the "big picture"/consistency/philosophy part. And here I see
that we have a way to indicate that a literal is: int, char, long,
signed, unsigned, wchar etc. but not if it represents a pointer. Seems
like a black hole, a missing puzzle - something for agent Mulder to
figure out: where did the pointer literals go, why does everyone say no
if asked about them. :-)
Attila
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Thu, 12 Sep 2002 18:57:23 +0000 (UTC) Raw View
In article <3D80C48B.E48CA572@lmf.ericsson.se>, Attila Feher
<Attila.Feher@lmf.ericsson.se> writes
>I am a kinda guy, who looks at the technical part (if understands it :-)
>and at the "big picture"/consistency/philosophy part. And here I see
>that we have a way to indicate that a literal is: int, char, long,
>signed, unsigned, wchar etc. but not if it represents a pointer. Seems
>like a black hole, a missing puzzle - something for agent Mulder to
>figure out: where did the pointer literals go, why does everyone say no
>if asked about them. :-)
That is a good point. However I think we need to face a bigger issue for
next time (and whether it also copes with pointer literals would be a
good test): how should we provide typed literals in C++. The traditional
mechanisms do not scale (there are a limited number of letters in the
alphabet.)
--
Francis Glassborow ACCU
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.jamesd.demon.co.uk/csc/faq.html ]
Author: gennaro_prota@yahoo.com (Gennaro Prota)
Date: Thu, 12 Sep 2002 19:34:29 +0000 (UTC) Raw View
On Wed, 11 Sep 2002 20:10:10 +0000 (UTC), hyrosen@mail.com (Hyman
Rosen) wrote:
>Gennaro Prota wrote:
>> Hyman Rosen wrote:
>>>0 was a null-pointer constant in C before void was even a
>>>keyword in that language.
>>
>> Are you kidding.
>
>No. C did not have a void keyword originally, but it
>did have the concept of 0 as a null pointer constant.
Yes. But I don't see how this applies to the fact that a C++ null
pointer constant cannot be (void*)0
>Even now, any integer constant expression whose value
>is 0 is a null pointer constant in C.
Which I know, as you may have seen from my example.
>> C++ explicitly prohibits this definition, why?
>
>No, C++ *implicitly* prohibits this definition. It is
>merely a consequence of the fact that C allows void *
>pointers to convert to other pointers without a cast.
Paragraph 4.10/1 says that a null pointer constant is an integral
constant expression, which of course excludes (void*)0.
>> If I had to change a rule, I would have prohibited everything
> > except (void*)0 and maybe, for historical reasons, the literal 0.
>
>The rule about integer constant expressions comes directly from C.
>Prohibiting it would be a gratuitous incompatibility. There could
>have been a special case made in C++ for such expressions cast to
>void *, and perhaps there should have been, but there wasn't. It
>doesn't affect much of anything.
>
>> Sometimes there are historical errors that have to be retained if you
>> don't want to break code. But think about what you break with the
>> change introduced in C++:
>>
>> // honest code - no more valid in C++
>> void f() {
>> void* null = 0;
>> char * p = null;
>> }
>
>// dishonest code - no more valid in C++, silent in C
>void f() {
> float f;
> void *pv = &f;
> int *pi = pv;
>}
Maybe you are missing my point. Nobody is asking for an implicit
conversion from void* to pointer-to-object. The discussion concerns
the null pointer constant only. There's no conversion from int to
pointer-to-object either, 0 works as a NPC because a special rule
allows it. Why can't a special rule exist for (void*)0 too?
Genny.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 12 Sep 2002 19:40:57 +0000 (UTC) Raw View
Attila Feher wrote:
> Hyman Rosen wrote:
> I don't get you. If this pointer literal thing is prepared on a way
> that it does not replace NULL but introduces a new, non-conflicting
> element why would it break your code?
That's not what I said. I just said that you couldn't get rid
of the old style. Furthermore, since the null pointer literal
would be a new addition, which you would have to modify the
code to use, why not just modify the code right now with a null
pointer constant cast to the right type?
The reaction I've seen here of "casts are bad" is silly, in the
same way that many arguments against all gotos are silly. When
you say (int *)0 or static_cast<int *>(0) you are not doing
anything questionable.
> Sure. As any other proposal.
Yes. But because it's such an effort, it's only worthwhile if
there is a significant payoff.
> I have to be very careful how to word this... But I hardly believ that
> you have seen _every_ real world application. I have it all around the
> one I see in front of me
As far as I can see, the problem occurs in two cases.
1) NULL is passed as an argument to a variadic function in an environment
where integers and pointers have different sizes, or where a null pointer
does not have an all-bits-zero representation.
2) There is a set of overloaded functions, some of which take a numeric
argument (or an argument constructible from some ineteger type), and
exactly one which takes a pointer type, and that function name is
called with NULL as a parameter.
You really have code which is full of this stuff?
It seems hard to believe.
> And I must say (with all respect) that these so far were opinions,
> yours. Not technical arguments. :-(
New features are not evaluated only against whether they can be made
to work, but also as to whether they are worth having relative to the
costs of specification, implementation, and understanding.
> Does this have _exactly_ the _same_ effect and behavior than the pointer
> literal would have?
I don't know, since the exact specification of the pointer literal doesn't
exist yet. One likely difference is that the literal is a compile-time
constant and the null object is not.
By the way, the idea that if we had 0p we could redefine NULL to be 0p is
wrong (or at least not backward compatible). Because of 18.1 and 4.10, it
is legal C++ to say 'char c = NULL;' and the change would break this.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 13 Sep 2002 16:58:41 +0000 (UTC) Raw View
Francis Glassborow wrote:
> how should we provide typed literals in C++.
With a cast, naturally. Why do you need anything else?
You might want to look into Ada's concept of Universal
integers and reals, which helps with this. Basically,
a numeric literal has arbitary precision as written,
and then gets converted to a particular type.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: agriff@tin.it (Andrea Griffini)
Date: Wed, 11 Sep 2002 08:44:49 +0000 (UTC) Raw View
On Tue, 10 Sep 2002 20:27:25 +0000 (UTC), gennaro_prota@yahoo.com
(Gennaro Prota) wrote:
>I wouldn't like to be in the place of the instructor that has to
>explain why
>
> A* p = (void*)0
>
>is illegal, whereas
>
> A* p = '\0';
>and
> A* p = L'\0';
>
>are well-formed.
I saw this happening unintentionally in real code...
someone making confusion using an array of char
pointers and having the program compiled anyway
just because '\0' can be a valid null pointer.
But things can get even worse than that... you
can have legally
A* p = 6502 - 0x1966;
I found no reason for which allowing any constant
integer expression usable instead of just the
integer literal 0 make any sense excluding having
fun in writing obfuscated code on intention.
I can't really see the good part of being able to
write things like Bjarne Stroustrup did
int *p = ! ! ! ! ! !
! ! ! ! ! ! !
! ! ! ! ! ! !
! ! !!!!!! !!!!! !!!!1;
(sorry for those of you that use a proportional
font for reading this group)
and no one gave any pertinent reply supporting
this when I asked in the past.
As for being the instructor what about trying to
distract students with something like "the lesson
is over" and quickly running out of the room ?
Andrea
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Attila.Feher@lmf.ericsson.se (Attila Feher)
Date: Wed, 11 Sep 2002 08:45:42 +0000 (UTC) Raw View
Hyman Rosen wrote:
>
> Yechiel Kimchi wrote:
> > Then the function call f(NULL)
>
> You are far from the first person to write about this.
> It just generates long and fruitless threads. The upshot
> is that no one important (i.e., in a position to change
> the rules) thinks this matters enough to do anything
> about. Neither do I.
While I see you might be tired of the topic it would still be nice if
youcould actually back up your disinterest or the stament of
no-importance with some technical facts. I mean I for one do not think
that just because we are used to a glitch in the language for ages
should automatically mean it makes no sense to think about it or making
it better.
If you could actually tell the _why_ do you think the topic is mute -
and I mean technical arguments, the above seems rather political - that
would help us to:
a.) understand it isn't worth touching
b.) get a step closer to a solution by seeing what is/was the problem
with the earlier proposals failing acceptance
Attila
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: gennaro_prota@yahoo.com (Gennaro Prota)
Date: Wed, 11 Sep 2002 16:39:19 +0000 (UTC) Raw View
On Tue, 10 Sep 2002 21:32:49 +0000 (UTC), hyrosen@mail.com (Hyman
Rosen) wrote:
>Gennaro Prota wrote:
>> I have never understood the choice of making 0, and not (void*)0,
> > a null pointer constant.
>
>0 was a null-pointer constant in C before void was even a
>keyword in that language.
Are you kidding. C++ was standardized 8 years later than C90, which
has void and allows NULL to be defined as (void*)0. C++ explicitly
prohibits this definition, why? If I had to change a rule, I would
have prohibited everything except (void*)0 and maybe, for historical
reasons, the literal 0. The standard made almost the opposite.
>> I wouldn't like to be in the place of the instructor
>
>C++ has any number of features that are as they are for
>historical reasons. One explains this and moves on.
Sometimes there are historical errors that have to be retained if you
don't want to break code. But think about what you break with the
change introduced in C++:
// honest code - no more valid in C++
void f() {
void* null = 0;
...
char * p = null;
...
}
// brain-dead code - retained
enum { e11 = 3 };
enum { e21, e22, e23, e24 };
void f() {
char * p = '\0';
p = e24 - e11;
p = 6/7;
}
Genny.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: thp@cs.ucr.edu
Date: Wed, 11 Sep 2002 18:01:07 +0000 (UTC) Raw View
thp@cs.ucr.edu wrote:
+ ===================================== MODERATOR'S COMMENT:
+ Please do keep any follow-ups topical, i.e., focused
+ on the standardisation of C++. Thank you.
+ ===================================== END OF MODERATOR'S COMMENT
+ Hyman Rosen <hyrosen@mail.com> wrote:
+ + Gennaro Prota wrote:
+ [...]
+ +> I wouldn't like to be in the place of the instructor
+ + C++ has any number of features that are as they are for
+ + historical reasons. One explains this and moves on.
+ ... or switches to Java.
My apologies for the facetious follow-up, and my appreciation to the
moderator for accepting/indulging it.
The comment is a plea that, in the context of the upcoming revisions to
the Standard, the committee take very seriously matters of
teachability and learnability. In D&E, Stroustrup notes that
teachability is one (of many) imporant goal of C++ design. IMHO, that
goal has been given relatively low weight. Perhaps that low weight
was appropriate, but there has been a cost in terms of mindshare.
This phenomenon is not new. Basic took mindshare from FORTRAN, Pascal
eclipsed Algol68 and PL/I, and C beat out Ada. Now Java is taking
mindshare from C++. In each case, the reason (IMHO) has been easier
learnability.
I don't claim to know the proper tradeoff for a standards change that
breaks a few billion dollars worth of legacy code but makes the
language easier to learn. Suppose, however, that you are the CEO of
an enterprise with $1B of such code. Suppose that it costs you $0.1B
to accomodate that change. How much will it cost you if all
undergraduate programs switch to Java? I.e., what kind of salary
premium will programmers of a legacy language be able to demand ten
years from now? We can't know the answer to that question, but the
Committee should know that when it decides between breaking legacy
code and learnability, it is deciding between near-term and long-term
costs.
<descending soapbox> ;-)
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Wed, 11 Sep 2002 18:01:14 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote in message
news:<C0Ye9.2425$5i.2384@nwrddc01.gnilink.net>...
> Yechiel Kimchi wrote:
> > Then the function call f(NULL)
> You are far from the first person to write about this. It just
> generates long and fruitless threads. The upshot is that no one
> important (i.e., in a position to change the rules) thinks this
> matters enough to do anything about.
Or that the people who are important can't reach a concensus as to how
radical the change should be. I'm pretty sure that if there were one
good solution, it would be adopted. The problem is that there are
several, differing in degrees of how much they affect the language as a
whole.
FWIW: g++ already generates a warning whenever NULL is used as an
integer, and has for quite some time now.
--
James Kanze mailto:jkanze@caicheuvreux.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Wed, 11 Sep 2002 18:32:12 +0000 (UTC) Raw View
Attila Feher wrote:
[...]
> If you could actually tell the _why_ do you think the topic is mute -
> and I mean technical arguments, ....
#include <iostream>
using namespace std;
struct C {
C* f(C*) { cout << "C::f(C*)" << endl; return 0; }
C* f(C*,C*) { cout << "C::f(C*,C*)" << endl; return 0; }
};
void f(char) { cout << "f(char)" << endl; }
void f(char*) { cout << "f(char*)" << endl; }
void f(const char*) { cout << "f(const char*)" << endl; }
void f(int) { cout << "f(int)" << endl; }
void f(int*) { cout << "f(int*)" << endl; }
void f(int**) { cout << "f(int**)" << endl; }
void f(float*) { cout << "f(float*)" << endl; }
void f(float**) { cout << "f(float**)" << endl; }
void f(int(*)()) { cout << "f(int(*)())" << endl; }
void f(int(**)()) { cout << "f(int(**)())" << endl; }
void f(C*) { cout << "f(C*)" << endl; }
void f(C**) { cout << "f(C**)" << endl; }
void f(C*(C::*)(C*)) { cout << "f(C*(C::*)(C*))" << endl; }
void f(C*(C::**)(C*)) { cout << "f(C*(C::**)(C*))" << endl; }
void f(C*(C::*)(C*,C*)) { cout << "f(C*(C::*)(C*,C*))" << endl; }
void f(C*(C::**)(C*,C*)) { cout << "f(C*(C::**)(C*,C*))" << endl; }
int blahblah() { cout << "blahblah" << endl; return 0; }
template< class T >
T* null_ptr()
{ return 0; }
template< class T >
T null_fun()
{ return 0; }
int main()
{
int(*func)() = &blahblah;
int(**pfunc)() = &func;
func();
(*pfunc)();
C c;
C*(C::*mfunc)(C*) = &C::f;
C*(C::**pmfunc)(C*) = &mfunc;
(c.*mfunc)(&c);
(c.**pmfunc)(&c);
f('\0');
f(null_ptr<char>());
f(null_ptr<const char>());
f(0);
f(null_ptr<int>());
f(null_ptr<int*>());
f(null_ptr<float>());
f(null_ptr<float*>());
f(null_fun<int(*)()>()); f(func);
f(null_fun<int(**)()>());f(pfunc);
f(null_ptr<int(*)()>()); f(pfunc);
f(null_ptr<C>());
f(null_ptr<C*>());
cout << "---" << endl;
f(null_fun<C*(C::*)(C*)>()); f(mfunc);
f(null_fun<C*(C::**)(C*)>());f(pmfunc);
f(null_ptr<C*(C::*)(C*)>()); f(pmfunc);
cout << "---" << endl;
f(null_fun<C*(C::*)(C*,C*)>());
f(null_fun<C*(C::**)(C*,C*)>());
return 0;
}
regards,
alexander.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Sep 2002 18:32:45 +0000 (UTC) Raw View
Attila Feher wrote:
> If you could actually tell the _why_ do you think the topic is mute -
"moot"
> and I mean technical arguments, the above seems rather political
You couldn't do away with using 0 as a null pointer constant
because of backward compatibility, so at best this would be a
feature applicable only to new code. This feature, as all others,
must be carefully specified, with attention as to how it interacts
with other aspects of the language. The end result of the chunk of
work is to paper over a minor fault in the language that probably
never, or hardly ever, shows up in real-world code, and if it did
is easily taken care of.
There are also roll-your-own solutions, along the lines of
static struct{template<class T>operator T*(){return 0;}}null;
So you can't do away with the old form, the new form doesn't
matter, and you can do it yourself anyway. These are the
classic reasons for not adopting a new feature.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Sep 2002 20:10:10 +0000 (UTC) Raw View
Gennaro Prota wrote:
> Hyman Rosen wrote:
>>0 was a null-pointer constant in C before void was even a
>>keyword in that language.
>
> Are you kidding.
No. C did not have a void keyword originally, but it
did have the concept of 0 as a null pointer constant.
Even now, any integer constant expression whose value
is 0 is a null pointer constant in C.
> C++ explicitly prohibits this definition, why?
No, C++ *implicitly* prohibits this definition. It is
merely a consequence of the fact that C allows void *
pointers to convert to other pointers without a cast.
> If I had to change a rule, I would have prohibited everything
> except (void*)0 and maybe, for historical reasons, the literal 0.
The rule about integer constant expressions comes directly from C.
Prohibiting it would be a gratuitous incompatibility. There could
have been a special case made in C++ for such expressions cast to
void *, and perhaps there should have been, but there wasn't. It
doesn't affect much of anything.
> Sometimes there are historical errors that have to be retained if you
> don't want to break code. But think about what you break with the
> change introduced in C++:
>
> // honest code - no more valid in C++
> void f() {
> void* null = 0;
> char * p = null;
> }
// dishonest code - no more valid in C++, silent in C
void f() {
float f;
void *pv = &f;
int *pi = pv;
}
> // brain-dead code - retained
So what? No one forces you to write code like that.
That it remains legal is a curiosity, but no more than
that. Meanwhile, the only issues with having NULL defined
as 0 are a couple of obscure overloads and passing it to
a variadic function. Big deal.
Why do you want a generic null pointer constant, anyway?
Why not just cast 0 the the pointer type?
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: gennaro_prota@yahoo.com (Gennaro Prota)
Date: Tue, 10 Sep 2002 20:27:25 +0000 (UTC) Raw View
On Tue, 10 Sep 2002 08:40:18 +0000 (UTC), hyrosen@mail.com (Hyman
Rosen) wrote:
>Yechiel Kimchi wrote:
>> Then the function call f(NULL)
>
>You are far from the first person to write about this.
>It just generates long and fruitless threads. The upshot
>is that no one important (i.e., in a position to change
>the rules) thinks this matters enough to do anything
>about. Neither do I.
I don't think so. Maybe you are correct as it concerns a
pointer-literal, but not about the null pointer problem in general. I
remember Mr. Glassborow saying he would like NULL to be elevated to a
value of a special incomplete type. BTW, I have never understood the
choice of making 0, and not (void*)0, a null pointer constant. What is
it? To avoid the special case of void* -> T* conversion we introduced
a special case of int -> T* conversion (and indeed from any integer
type to T*)?
I wouldn't like to be in the place of the instructor that has to
explain why
A* p = (void*)0
is illegal, whereas
A* p = '\0';
and
A* p = L'\0';
are well-formed.
Genny.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 10 Sep 2002 21:32:49 +0000 (UTC) Raw View
Gennaro Prota wrote:
> I have never understood the choice of making 0, and not (void*)0,
> a null pointer constant.
0 was a null-pointer constant in C before void was even a
keyword in that language.
> I wouldn't like to be in the place of the instructor
C++ has any number of features that are as they are for
historical reasons. One explains this and moves on.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: thp@cs.ucr.edu
Date: Tue, 10 Sep 2002 23:18:34 +0000 (UTC) Raw View
===================================== MODERATOR'S COMMENT:
Please do keep any follow-ups topical, i.e., focused
on the standardisation of C++. Thank you.
===================================== END OF MODERATOR'S COMMENT
Hyman Rosen <hyrosen@mail.com> wrote:
+ Gennaro Prota wrote:
[...]
+> I wouldn't like to be in the place of the instructor
+ C++ has any number of features that are as they are for
+ historical reasons. One explains this and moves on.
... or switches to Java.
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: swu00@earthlink.net (Shao Wu)
Date: Mon, 9 Sep 2002 19:01:26 +0000 (UTC) Raw View
Yechiel Kimchi wrote:
>
> Here is my suggestion: Add a new type of literals
> to C++, call them pointer-literals.
> pointer-literal:
> unsuffixed-integer-literal pointer-suffix
>
> pointer-suffix: one of
> p P
>
> (the unsuffixed-integer-literal has the obvious meaning)
>
> Having those added, a call f(0P) will be bound to f(int*)
> in the first case, and will invoke a syntax error from
> the compiler if the fourth function is in scope.
> Then, NULL can be #defined to be 0P, and preserve
> the traditional semantics.
this pointer literal solves the problem with f(int) and f(int*),
but what happen if I have f(double*), f(SomeClass*)? Pointer
literal would not help.
Shao
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 10 Sep 2002 08:40:18 +0000 (UTC) Raw View
Yechiel Kimchi wrote:
> Then the function call f(NULL)
You are far from the first person to write about this.
It just generates long and fruitless threads. The upshot
is that no one important (i.e., in a position to change
the rules) thinks this matters enough to do anything
about. Neither do I.
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: yechiel@cs.Technion.AC.IL (Yechiel Kimchi)
Date: Thu, 5 Sep 2002 18:15:46 +0000 (UTC) Raw View
Here is a possible (common ?) situation:
Suppose we have the following declarations
void f(int);
void f(char);
void f(int *);
Then the function call f(NULL)
will fail to do what is clearly intended.
This is because in C++ NULL is 0
(and not (void*)0 as is common in C).
Recall that in C, the function call f(NULL)
will fail if f() does not expect a pointer.
The problem is that while 0 serves well in all
of the primitive types (as above and more) it is
nevertheless "more" of type int than anything else.
Therefore, C++ inherited from C some variations
for representing 0 of other types, '\0', 0., 0L, etc.
Alas, there is nothing like that for pointers
and the example above shows that bugs may be
introduced without any warning from the compiler.
Moreover, suppose there was a fourth function
in scope, say, void f(double*).
Then, there would not be a warning
(though the function call f(NULL) is ambiguous)
because the wrong function is invoked anyway.
Here is my suggestion: Add a new type of literals
to C++, call them pointer-literals.
pointer-literal:
unsuffixed-integer-literal pointer-suffix
pointer-suffix: one of
p P
(the unsuffixed-integer-literal has the obvious meaning)
Having those added, a call f(0P) will be bound to f(int*)
in the first case, and will invoke a syntax error from
the compiler if the fourth function is in scope.
Then, NULL can be #defined to be 0P, and preserve
the traditional semantics.
Although the above problem can be, somehow, solved
by a template class
template <typename T> class nil {
public: operator T*() const {return (T*)0;}
};
the usage f(nil<int>()) is more cumbersome than f(NULL)
and should be reserved to solve ambiguities.
In addition (and in order to make it a general concept)
it is possible to allow any literal (e.g, 67P, 0xdeadbeefP)
to be legal, with an implementation dependent semantics.
Formally, the semantics of a pointer-literal will be
as an unspecified/unnamed pointer-type (as if it is the type
that is derived from all pointer types - so it is
compatible with all pointer-types).
With respect to typeid of such objects,
these will have their typeid() evaluated statically,
because they are not lvalues.
Enjoy
Happy New Year
Yechiel
--------------------------------------------------------------------------------
Have you looked at recent updates to "Bad Books Amusement Park" ?
Try http://www.cs.technion.ac.il/users/yechiel/CS/BadBooksC+C++.html
Yechiel M. Kimchi yechiel@cs.technion.ac.il
Homepage: http://www.cs.technion.ac.il/users/yechiel/
---
[ comp.std.c++ is moderated. To submit articles, try 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.jamesd.demon.co.uk/csc/faq.html ]
Author: bop2@telia.com ("Bo Persson")
Date: Thu, 5 Sep 2002 20:09:05 +0000 (UTC) Raw View
"Yechiel Kimchi" <yechiel@cs.Technion.AC.IL> skrev i meddelandet
news:200209051812.g85ICeu17634@cs.Technion.AC.IL...
>
> Here is a possible (common ?) situation:
>
> Suppose we have the following declarations
>
> void f(int);
> void f(char);
> void f(int *);
>
> Then the function call f(NULL)
> will fail to do what is clearly intended.
> This is because in C++ NULL is 0
> (and not (void*)0 as is common in C).
> Recall that in C, the function call f(NULL)
> will fail if f() does not expect a pointer.
>
> The problem is that while 0 serves well in all
> of the primitive types (as above and more) it is
> nevertheless "more" of type int than anything else.
>
>
> Here is my suggestion: Add a new type of literals
> to C++, call them pointer-literals.
> pointer-literal:
> unsuffixed-integer-literal pointer-suffix
>
> pointer-suffix: one of
> p P
>
> (the unsuffixed-integer-literal has the obvious meaning)
>
> Having those added, a call f(0P) will be bound to f(int*)
What is wrong with the equally ugly f((int*)0) ?
Hopefully pointer literals would be extremely unlikely anyway, so why not
make it hard to use them?
This is somewhat like the new casts, which are big and ugly so you would be
ashamed to show them in your code walkthrus. Works fine!
Bo Persson
bop2@telia.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.jamesd.demon.co.uk/csc/faq.html ]