Is it safe to #define NULL nullptr?

前端 未结 6 848
囚心锁ツ
囚心锁ツ 2021-02-02 06:38

I have seen below macro in many topmost header files:

#define NULL 0  // C++03

In all over the code, NULL and 0 are u

相关标签:
6条回答
  • 2021-02-02 06:55

    Far better is to search and replace NULL with nullptr throughout the code.

    It may be syntactically safe, but where would you put the #define? It creates code organisation problems.

    0 讨论(0)
  • 2021-02-02 06:55

    You shouldn't be defining it at all, unless you're writing your own version of <cstddef>; it certainly shouldn't be in "many topmost header files".

    If you are implementing your own standard library, then the only requirement is

    18.2/3 The macro NULL is an implementation-defined C++ null pointer constant

    so either 0 or nullptr is acceptable, and nullptr is better (if your compiler supports it) for the reason you give.

    0 讨论(0)
  • 2021-02-02 07:06

    I have seen below macro in topmost header file:

    You shouldn't have seen that, the standard library defines it in <cstddef> (and <stddef.h>). And, IIRC, according to the standard, redefining names defined by standard header files results in undefined behaviour. So from a purely standardese viewpoint, you shouldn't do that.


    I've seen people do the following, for whatever reason their broken mind thought of:

    struct X{
      virtual void f() = NULL;
    }
    

    (As in [incorrectly]: "set the virtual table pointer to NULL")

    This is only valid if NULL is defined as 0, because = 0 is the valid token for pure-virtual functions (§9.2 [class.mem]).

    That said, if NULL was correctly used as a null pointer constant, then nothing should break.

    However, beware that, even if seemingly used correctly, this will change:

    void f(int){}
    void f(char*){}
    
    f(0); // calls f(int)
    f(nullptr); // calls f(char*)
    

    However, if that was ever the case, it was almost certainly broken anyways.

    0 讨论(0)
  • 2021-02-02 07:07

    No. You're not allowed to (re)define standard macros. And if you see

    #define NULL 0
    

    at the top of any file other than a standard header (and even there, it should be in include guards, and typically in additional guards as well), then that file is broken. Remove it.

    Note that good compilers will typically define NULL with something like:

    #define NULL __builtin_null
    

    , to access a compiler builtin which will trigger a warning if it is used in a non-pointer context.

    0 讨论(0)
  • 2021-02-02 07:11

    While it might break backwards-compatibility with older stuff that was badly written (either that, or overly clever...), for your newer code, this is a non-issue. You should use nullptr, and not NULL, where you mean nullptr. Also, you should use 0 where you mean zero.

    0 讨论(0)
  • 2021-02-02 07:13

    Maybe Not

    If you have a particular format of overloading behaviour:

    void foo(int);
    void foo(char*);
    

    Then the behaviour of the code:

    foo(NULL);
    

    will change depending on whether NULL is changed to nullptr or not.

    Of course, there's another question as to whether it's safe to write such code as is present in this answer...

    0 讨论(0)
提交回复
热议问题