Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

Pure Software Engineer :)

[Item 8] Prefer nullptr to 0 and NULL 본문

Software Engineering/Programming

[Item 8] Prefer nullptr to 0 and NULL

HelloJaewon 2014. 12. 7. 22:05

The literal 0 is an int, not a pointer.

// three overloads of f void f (int); void f (bool); void f (void *);  f(0);    // call f(int), not f(void *)  f(NULL);    // might not compile, but typically calls f(int). Never calls f(void*) 

This counterintuitive is what led to the guideline for C++98 programmers to avoid overloading on pointer and integral types.

That guideline remains valid in C++11, because, the advice of this item notwithstanding, it's likely that some developers will continue to use 0 and NULL, even though nullptr is a better choice.

Advantages of nullptr

  • It doesn't have an integral type.
f(nullptr);    // calls f(void*) overload 
  • It can also improve code clarity.
auto result = findRecord( /* arguments */ );  if (result == 0) {     .... } 
auto result = findRecord( /* arguments */ );  if (result == nullptr) {     .... } 
  • nullptr shines especially brightly when templates enter the picture.
// call these only when the appropriate mutex is locked int f1 (std::shared_ptr<WIdget> spw); double f2 (std::unique_ptr<Widget> upw); bool f3 (Widget * pw);  std::mutex f1m, f2m, f3m;    // mutexes for f1, f2 and f3  using MuxGuard = std::lock_guard<std::mutex>;    // C++ typedef; see Item 9 ... {     MuxGuard g(f1m);    // lock mutex for f1     auto result = f1(0);    // pass 0 as null ptr to f }                                    // unlock mutex ... {     MuxGuard g(f2m);    // lock mutex for f2     auto result = f2(NULL);    // pass NULL as null ptr to f2 }                                           // unlock mutex ... {     MuxGuard g(f3m);    // lock mutex for f3     auto result = f3(nullptr);    // pass nullptr as null ptr to f3 }                                            // unlock mutex 
template<typename FuncType,                 typename MuxType,                 typename PtrType> auto lockAndCall (FuncType func,                              MuxType & mutex,                              PtrType ptr) -> decltype(func(ptr)) {     MuxGuard g(mutex);     return func(ptr); }  auto result1 = lockAndCall(f1, f1m, 0);    // error! ... auto result2 = lockAndCall(f2, f2m, NULL);    // error! ... auto result3 = lockAndCall(f3, f3m, nullptr);    // fine 
template<typename FuncType,                 typename MuxType,                 typename PtrType> decltype(auto) lockAndCall (FuncType func,    // C++14                              MuxType & mutex,                              PtrType ptr) {     MuxGuard g(mutex);     return func(ptr); } 

Things to Remember

  • Prefer nullptr to 0 and NULL.
  • Avoid overloading on integral and pointer types.