
On 12/5/2012 8:59 AM, Nathan Crookston wrote:
Andrey Semashev wrote:
Felipe Magno de Almeida wrote:
Andrey Semashev wrote:
Eric Niebler wrote:
[snip]
... and Microsoft's min/max macros cause no problems because they can be disabled with NOMINMAX. :-P
I don't see how this is related. We're not making nullptr a macro, it still obeys scoping rules.
If it is global, then it is all scopes. And it can't even be qualified, because nullptr is never used qualified in user code.
I find reiterating myself. Yes, it is global but it's not a macro. The global using declaration is optional and can be disabled if there's another global nullptr available (a very slim probability). Other than the global import, it does not conflict with any other implementation (i.e. in another scope).
So, is there a use case that is broken with this approach that I'm missing?
I would be concerned if I were using a library (A) which used boost.nullptr and another library (B) which shipped its own, potentially at global scope.
I can disable the global using declaration, but if library A is using it unqualified, as suggested, then wouldn't I need to update that library's code? Or would they be required to check for the disabling macro?
Precisely. Before boost had its min/max guidelines, we used to tell people to just compile with NOMINMAX when conflicts arose. Then we learned that some of Microsoft's own Platform SDK headers don't compile in that configuration. This situation can happen not just for macros but also for conditionally-defined global variables. Which is why I brought the example up.
I wonder if it wouldn't be better to have something like the following:
namespace boost { namespace detail { class nullptr_t {...}; }
#ifdef BOOST_CXX11_NO_NULLPTR typedef boost::detail::nullptr_t nullptr_t; #else typedef std::nullptr_t nullptr_t; #endif
namespace { const boost::detail::nullptr_t nullptr_ = {}; } }//end boost
And user code would use boost::nullptr_ of type boost::nullptr_t.
It's not as nice as using straight nullptr, but I think it will interoperate better, since we're not constrained to suggest using it unqualified due to the nullptr keyword.
I for one will simply be using 0 in code that needs to be portable. I don't feel the need for anything fancier. I might consider using a BOOST_NULLPTR macro if it were defined like this: #if c++11 // <-- psuedo-code #define BOOST_NULLPTR nullptr #else #define BOOST_NULLPTR 0 #endif I'm not partial to the above suggestion from Nate because AFAIK there is no way for a user-defined type to perfectly emulate nullptr, and there is no migration path to C++11. But it's preferable to putting a nullptr identifier in the global scope, IMO. -- Eric Niebler BoostPro Computing http://www.boostpro.com