Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NULL macro or NULL const [duplicate]

I am currently in the process of reading a book on C++, and in this book the author explains that it is better to use a constant rather than NULL macro, but without really explaining why or giving any advantages or disadvantages.

So why it's better to do use:

const int NULL = 0;
int *ptr = NULL;

instead of:

int *ptr = NULL;

The only explanation is given is that the NULL macro is not type-safe.

like image 588
simon Avatar asked May 17 '16 07:05

simon


People also ask

Is Nullptr a macro?

Null macro is defined in stdio. h and stddef.h.It is used to represent a null pointer in your code. its value is zero. Null pointer is same as an uninitialized pointer..

Is null a macro for 0?

Traditionally, the NULL macro is an implementation defined constant representing a null pointer, usually the integer 0 . In C, the NULL macro can have type void * .

What is the difference between NUL and null in C?

The C NUL is a single character that compares equal to 0. The C NULL is a special reserved pointer value that does not point to any valid data object. The SQL null value is a special value that is distinct from all non-null values and denotes the absence of a (non-null) value.

Is it null or NUL?

It is often abbreviated as NUL (or NULL, though in some contexts that term is used for the null pointer). In 8-bit codes, it is known as a null byte. The original meaning of this character was like NOP—when sent to a printer or a terminal, it has no effect (some terminals, however, incorrectly display it as space).


4 Answers

All are out of date.

Use nullptr instead. That's a special value for a pointer that doesn't point to anything. It even has its own type, std::nullptr_t.

There's no guarantee that the address 0x0 corresponds to the "uninitialised" pointer value, but note that the literal 0 is guaranteed to convert to the null pointer value.

like image 145
Bathsheba Avatar answered Oct 10 '22 14:10

Bathsheba


If you are using C++11 then its advisable to use nullptr instead of NULL.

Below are a few lines from The C++ Programming Language by Bjarne Stroustrup

  • In older code, 0 or NULL is typically used instead of nullptr (§7.2.2). However, using nullptr eliminates potential confusion between integers (such as 0 or NULL) and pointers (such as nullptr).
  • there are differences in the definition of NULL in different implementations; for example, NULL might be 0 or 0L. In C, NULL is typically (void∗)0, which makes it illegal in C++ (§7.2.1):
  • Using nullptr makes code more readable than alternatives and avoids potential confusion when a function is overloaded to accept either a pointer or an integer

I hope this will help you to understand.

like image 33
Manthan Tilva Avatar answered Oct 10 '22 13:10

Manthan Tilva


Indeed, the "NULL macro" is not type-safe. That means your compiler doesn't know if you're using the right type. For example, when using memcpy:

SomeClass a;
AnotherClass b;
memcpy((void*)&a, (void*)&b, sizeof(b));

(taken from there)

The compiler only sees two pointers in memory. But SomeClass and AnotherClass are incomplete types.

As others said, if you can use C++11, just use nullptr.

like image 41
Rosh Donniet Avatar answered Oct 10 '22 14:10

Rosh Donniet


The author is right that preprocessor macros are not typed (in contrary to e.g. variables, where typing is enforced during their declaration). So macros are more dangerous in this regard, as compiler is unable to verify type correctness in expressions and you may miss an important warning/error message during compilation

Of course compiler creators can (and usually do, I hope) provide a version of NULL macro that expands to a value with a cast, equivalent (not identical!) to the C definition:

#define N ((void*)0)

BTW: since C++11 NULL can evaluate to std::nullptr_t type.

So I would not expect too much problems with NULL, but you may consider avoiding using your own macros. Or at least use your macros with caution as long as you are not perfectly sure that you can foresee the many contexts in which your macro may happen to be expanded in various expressions.

For a short exercise, you can try the below, to see that macros have no type, so their type gets deduced in the expressions, subject to e.g. arithmetic conversions or promotions. In the below example, MY_NULL macros (=without casting) result in quite dangerous assignments. That is what your book author has in mind and tries to warn you.

MY_TYPED macros evaluate to casted expressions, which ensures that compilers catches error when trying e.g. i = MY_TYPED_NULL;

#define MY_NULL 0
#define MY_TYPED_NULL ((void*)0)
int i;
float f;
void* v;
i = MY_NULL;    // bad: no compiler error
f = MY_NULL;    // bad: no compiler error
v = MY_NULL;    // seems to match programmer's intention
i = MY_TYPED_NULL;    // good: compiler error
f = MY_TYPED_NULL;    // good: compiler error
v = MY_TYPED_NULL;    // correct
like image 44
Artur Opalinski Avatar answered Oct 10 '22 14:10

Artur Opalinski