Example:
Type safetyCode:inline template <typename T> T *NullPtr() { return 0; }
Example:
Type safetyCode:inline template <typename T> T *NullPtr() { return 0; }
Well actually, I don't think it's the same.
I'm all for allowing nullptr because it will increase type safety.
What I don't really see a problem with is to use NULL for initializing pointers rather than 0.
This is exactly how it should be used:
This is exactly how it should not be used (and preferably, it should not compile):Code:int* ptr = NULL;
Code:int num = NULL;And I love the idea of the second example failing to compile.However, it is not the same to type:
As it would be to writeCode:int* ptr = nullptr;
Code:int num = nullptr;
Oh, I do not see a problem with that either. They are, after all, effectively the same.What I don't really see a problem with is to use NULL for initializing pointers rather than 0.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
In the current standard, I'd rather use NULL to initialize pointers than 0, because NULL effectively says it's a NULL pointer.
I see NULL as a type that can only be assigned to pointers.
0 on the other hand is an integer and so shouldn't really be assigned to pointers, in my opinion.
In this regard, nullptr is a good addition methinks.
0 also effectively says that it is a null pointer.In the current standard, I'd rather use NULL to initialize pointers than 0, because NULL effectively says it's a NULL pointer.
I think you mean "value" rather than "type".I see NULL as a type that can only be assigned to pointers.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
I think the abstraction of NULL away from 0 is a sensible one, particularly considering the fact that a NULL pointer does not necessarily have to be represented by all of it's bits being 0. Even though asigning 0 to it must set the pointer to the NULL value used by that platform. Memsetting a pointer to 0 is NOT the same as assigning 0, on obscure platforms!
When people take away the abstraction we call NULL, and just use 0 instead, they're likely to do the memset thing and write unportable code.
I welcome the new and better abstraction called nullptr.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
This is one area where the C standard definition of NULL will at least throw a compile-time error. In C NULL is a pointer. How nullptr has not existed all this time is puzzling.
--vvOriginally Posted by N1124 7.17.3Originally Posted by N1124 6.3.2.3.3
The discussion on null is all well an good; however the main issue is still un-addressed:
what are the types of the following expressions:
(int)NULL
(long)NULL
(int)(void *)NULL
where NULL = nullptr vs any other definition. According to the definition above, they should be int, long, and int.
Put another way: under what circumstances will "(int)NULL" not evaluate to an integer type?
Just to clarify: how it is to be used is of no concern. If I want to shoot myself in the foot by assigning NULL to an integer, I should be able to do so warning-free, granted that I inform the compiler of my intention (i.e. an explicit cast).
The conversion (int)something is required to fail (and a compiler error is normally expected) if "something" is of a type that cannot be converted to int.
Forcing the issue with an explicit conversion does not achieve much if the compiler does not know how to do the conversion.
How it is used is of concern. One of the attributes of undefined behaviour is that anything is allowed to happen. Failing to compile your code is one of the acceptable possibilities supported by "anything".
You may wish to shoot yourself in the foot via an indirect route. However, a compiler (or library) is not required to allow all steps in that indirect route to succeed.
Do you only get that warning when casting NULL, or do you also get it when casting a non-NULL pointer?
I would certainly expect that a C-style cast should tell the compiler to shut up and do what I tell it, so I'd be interested to know why it's doing that, even though I'd never actually do that in real life.
"I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008
"the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010
(int)(void *)0 is also accepted. You share my awe, I fully expected a C-style casting to be "putting the foot down", and what's more is that it is, when it comes to casting to long and char, but just not int (see the above example).
@grumpy, here's the jaw-dropper though: how pray tell, could it not know how to convert some type to int, that it will readily convert to long and char!?
It surely cannot be a primitive type (since those can be readily converted), so even if we were to assume it is of type FOO, it makes no sense why any compiler would allow FOO to char and FOO to long conversions where it will not allow FOO to int.
I certainly agree that you should be unable to assign NULL to a non-pointer. Using an explicit cast to make it work is an evil workaround and I'm not sure such a thing should be allowed.
It probably happens due implicit conversion.
It has overloaded one or more operators, for example int, and when invoked, produces a warning.
However, since it's a nullptr, it may very well provide a void* implicit operator and void* can then be cast to int without a warning, so that would explain that. As for the rest, it may be that that it uses an implicit operator such as void* first and then casting the result to long, skipping the warning altogether.
The reason, as suggested by Elysia, is probably that a conversion to int has not been implemented, but a conversion to char or long has. It is possible to get the same effect fairly easily with standard C++ too.
As to why your version of g++ is doing it with a NULL pointer ..... the obvious explanations are a deliberate design decision (i.e they decided to do it that way) or an oversight - either way, whatever the type of NULL is, it cannot be converted to an int.Code:#include <iostream> class Foo { public: operator char() {return '\0';}; operator long() {return 0L;}; // whoops! forgot to implement an operator int(). }; int main() { Foo x; // If a macro named NULL is not defined, I could name my variable NULL. // However, I won't do that .... std::cout << (char)x; // fine std::cout << (long)x; // fine std::cout << (int)x; // error }
My guess, incidentally, is that it is deliberate. Quite a few functions in the standard library where a programmer will be tempted - as you are - to pass a NULL accept an int argument or two. There are relatively few functions in the standard library where a programmer will be tempted to pass a NULL to a function expecting a char or a long. Disabling the conversion of NULL (or whatever type NULL is) to int will give the sort of diagnostic you're experiencing, but there was probably no anticipated use cases where a programmer would be silly enough to pass NULL where a char or long is expected.
If you argue they shouldn't do that. then fine. Find one example where such a conversion of NULL to int is actually necessary for a program to work - portably.
Otherwise accept the behaviour of the compiler for what it is: diagnosing a code construct that is likely to get you in trouble at some point.