Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't you take the address of nullptr?

In the C++11 standard, I don't understand the reason why taking the address of nullptr is disallowed whereas one is allowed to take the address of their own std::nullptr_t instances. Aside from the fact that nullptr is a reserved keyword, is there any designated reasoning for this decision?

Simply because it amuses me, I attempted to circumnavigate this restriction with the following function:

decltype(nullptr)* func(const decltype(nullptr) &nref) noexcept {     return const_cast<decltype(nullptr)*>(reinterpret_cast<const decltype(nullptr)*>(&nref)); } 

I had to use reinterpret_cast on the parameter because without it I was getting the hysterical error:

error: invalid conversion from 'std::nullptr_t*' to 'std::nullptr_t*' [-fpermissive] 

When I call this function by passing nullptr directly I get a different address each time. Is nullptr dynamically assigned an address just-in-time for comparisons and such? Or (probably more likely) perhaps is the compiler forcing a temporary copy of the underlying object?

Of course none of this is vital information, I just find it interesting why this particular restriction was implemented (and subsequently why I am seeing the behavior I am).

like image 957
monkey0506 Avatar asked Jan 07 '13 04:01

monkey0506


People also ask

Can this be nullptr?

Due to the nature of undefined behavior, you can simplify the statement to simply be " this is never nullptr " since no rule needs to be upheld in the presence of undefined behavior. You're right.

Can you return a nullptr in C++?

Just return '0' (zero). That is the representation of a null pointer in C++. nullptr would be better, but seriously, use std::find_if and preferably a std::vector<Person> without the pointer.

Why is a pointer with a value of 0 Not a valid address?

It's not even an address abstraction, it's the constant specified by the C standard and the compiler can translate it to some other number as long as it makes sure it never equals a "real" address, and equals other null pointers if 0 is not the best value to use for the platform.

Should I initialize a pointer to nullptr?

No, you don't have to set it to NULL , but some consider it good practice as it gives a new pointer a value that makes it explicit it's not pointing at anything (yet). If you are creating a pointer and then immediately assigning another value to it, then there's really not much value in setting it to NULL .


2 Answers

It's the same as not being able to take the address of 5 even though you can take the address of an int after giving it the value 5. It doesn't matter that there's no alternative value for a nullptr_t to have.

Values don't have addresses; objects do.

A temporary object is generated when you pass such a value to a const & parameter, or otherwise bind a value to a const reference, such as by static_cast< T const & >( … ) or declaring a named reference T const & foo = …;. The address you're seeing is that of the temporary.

like image 144
Potatoswatter Avatar answered Oct 21 '22 15:10

Potatoswatter


If you're after a standard answer, § 18.2/9 puts your observations pretty bluntly:

Although nullptr’s address cannot be taken, the address of another nullptr_t object that is an lvalue can be taken.

Alternatively, § 2.14.7 says this about nullptr:

The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t.

So what is a prvalue? § 3.10/1 answers that:

A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [ Example: The result of calling a function whose return type is not a reference is a prvalue. The value of a literal such as 12, 7.3e5, or true is also a prvalue. — end example ]

Hopefully, trying to take the address of any of those things in the example will make more sense as to why you can't take the address of nullptr. It's part of those examples!

like image 25
chris Avatar answered Oct 21 '22 13:10

chris