Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


#ActualSiCrane

Posted 15 December 2012 - 05:28 AM

#2: 0 is the only literal constant that is defined by the standard to be implicitly castable to a pointer of any kind,

No, any integer constant expression that evaluates to zero is a valid null pointer constant. This includes 0 but also includes (1-1), (0xful >> 10), and '\0'. The standard specifically lists both 0 and 0L as two legal options for NULL. The latter is used by some compilers where an int is not the same size as a pointer, but a long is. This can give narrowing conversion warnings when trying to assign a NULL to a regular int. See the previously mentioned sections 8.1 in C++98/C++03 and 8.2 in C++11, as well as sections 4.10 and 5.19 (same number for all three).

I would just redefine NULL as nullptr since I would probably also build the source on C++0x/C++11 complaint compilers, Of course, you loose the type of nullptr when compiling for pre-C++0x (std::nullptr_t) but with a little care (only load/store and compare with pointers), I cannot see why it would cause trouble.

Again, as previously mentioned, NULL has an integer type which does not play happily with things like function overloads and template type deduction. If you have an overloaded function void foo(int) and void foo(void *), foo(NULL) calls the first overload but foo(nullptr) calls the second overload. Similarly if you have a vector<int *>, std::fill(vec.begin(), vec.end(), NULL) will fail to compile but std::fill(vec.begin(), vec.end(), nullptr) should.

const void *nullptr = (unsigned)NULL;

This is not a valid replacement for the C++11 nullptr. First, as previously mentioned, a void pointer cannot be assigned to other pointer types without an explicit cast. Basic usage such as int * a = nullptr; would fail. Second, this isn't a constant expression. You've defined nullptr as a non-const pointer to const void. Presumably you wanted some variation with const on the right hand side of the * to make the pointer itself const. But also, even when dealing with void pointers you can still get into a situation where you need a cast because a const void * is not assignable to a volatile void * without a cast.

#1SiCrane

Posted 15 December 2012 - 05:26 AM

#2: 0 is the only literal constant that is defined by the standard to be implicitly castable to a pointer of any kind,

No, any integer constant expression that evaluates to zero is a valid null pointer constant. This includes 0 but also includes (1-1), (0xful >> 10), and '\0'. The standard specifically lists both 0 and 0L as two legal options for NULL. The latter is used by some compilers where an int is not the same size as a pointer, but a long is. This can give narrowing conversion warnings when trying to assign a NULL to a regular int. See the previously mentioned sections 8.1 in C++98/C++03 and 8.2 in C++11, as well as sections 4.10 and 5.19 (same number for all three).

I would just redefine NULL as nullptr since I would probably also build the source on C++0x/C++11 complaint compilers, Of course, you loose the type of nullptr when compiling for pre-C++0x (std::nullptr_t) but with a little care (only load/store and compare with pointers), I cannot see why it would cause trouble.

Again, as previously mentioned, NULL has an integer type which does not play happily with things like function overloads and template type deduction. If you have an overloaded function void foo(int) and void foo(void *), foo(NULL) calls the first overload but foo(nullptr) calls the second overload. Similarly if you have a vector<int *>, std::fill(vec.begin(), vec.end(), NULL) will fail to compile but vector<int *>, std::fill(vec.begin(), vec.end(), nullptr) should.

const void *nullptr = (unsigned)NULL;

This is not a valid replacement for the C++11 nullptr. First, as previously mentioned, a void pointer cannot be assigned to other pointer types without an explicit cast. Basic usage such as int * a = nullptr; would fail. Second, this isn't a constant expression. You've defined nullptr as a non-const pointer to const void. Presumably you wanted some variation with const on the right hand side of the * to make the pointer itself const. But also, even when dealing with void pointers you can still get into a situation where you need a cast because a const void * is not assignable to a volatile void * without a cast.

PARTNERS