[config] Macro for null pointer

I have found something like this to be helpful, when working with multiple compilers: #include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed. Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ? Edward Diener

On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <eldiener@tropicsoft.com>wrote:
I have found something like this to be helpful, when working with multiple compilers:
#include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif
where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed.
Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ?
Might it be better to just offer a (albeit imperfect) nullptr emulation if not supplied by the compiler? For example, [1]. - Jeff [1] http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/nullptr

2012/11/16 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>:
On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <eldiener@tropicsoft.com>wrote:
I have found something like this to be helpful, when working with multiple compilers:
#include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif
where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed.
Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ?
Might it be better to just offer a (albeit imperfect) nullptr emulation if not supplied by the compiler? For example, [1].
- Jeff
[1] http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/nullptr
`nullptr_t` is also required for libraries (especially for Boost.SmartPtr). So there must be a macro for it too. And may be we shall typedef nullptr_t as boost::none_t ? -- Best regards, Antony Polukhin

On Fri, Nov 16, 2012 at 1:39 AM, Antony Polukhin <antoshkka@gmail.com>wrote:
And may be we shall typedef nullptr_t as boost::none_t ?
I'm not entirely sure about this, but I'm not really sure that I'm against it either. I just wonder if there might be some weird situations where it could cause ambiguity or other problems. For instance, could this maybe cause a problem or questionable/unintuitive behavior with something like optional<int*>? Perhaps that's a weird case, but without some investigation I'm willing to bet there might be some more subtleties. -- -Matt Calabrese

2012/11/16 Matt Calabrese <rivorus@gmail.com>
On Fri, Nov 16, 2012 at 1:39 AM, Antony Polukhin <antoshkka@gmail.com
wrote:
And may be we shall typedef nullptr_t as boost::none_t ?
I'm not entirely sure about this, but I'm not really sure that I'm against it either. I just wonder if there might be some weird situations where it could cause ambiguity or other problems. For instance, could this maybe cause a problem or questionable/unintuitive behavior with something like optional<int*>? Perhaps that's a weird case, but without some investigation I'm willing to bet there might be some more subtleties.
I also believe this may cause problems. See this discussion on not using nullptr for the proposed std::optional: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3406.html#rationale... Regards, &rzej

On 16/11/12 18:18, Andrey Semashev wrote:
On November 16, 2012 10:39:30 AM Antony Polukhin <antoshkka@gmail.com> wrote:
And may be we shall typedef nullptr_t as boost::none_t ?
nullptr_t should be implicitly convertible to any pointer type, which none_t isn't AFAIR.
Are there any unit tests for nullptr floating around? Compiler vendors perhaps?

Antony Polukhin wrote
2012/11/16 Jeffrey Lee Hellrung, Jr. <
jeffrey.hellrung@
>:
On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <
eldiener@
>wrote:
I have found something like this to be helpful, when working with multiple compilers:
#include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif
where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed.
Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ?
Might it be better to just offer a (albeit imperfect) nullptr emulation if not supplied by the compiler? For example, [1].
- Jeff
[1] http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/nullptr
`nullptr_t` is also required for libraries (especially for Boost.SmartPtr). So there must be a macro for it too.
And may be we shall typedef nullptr_t as boost::none_t ?
Why a library will need a type nullptr_t while there is only a constant in C++11? Please coul you elaborate? Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/config-Macro-for-null-pointer-tp4638690p4... Sent from the Boost - Dev mailing list archive at Nabble.com.

2012/11/16 Vicente Botet <vicente.botet@wanadoo.fr>:
Why a library will need a type nullptr_t while there is only a constant in C++11? Please coul you elaborate?
According to draft of C++11 (I have no final version): Pointer literals [lex.nullptr] pointer-literal:nullptr The pointer literal is the keyword `nullptr`. It is a prvalue of type `std::nullptr_t`. [ Note: `std::nullptr_t` is a distinct type that is neither a pointer type nor a pointer to member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. -- Best regards, Antony Polukhin

Le 16/11/12 13:55, Antony Polukhin a écrit :
2012/11/16 Vicente Botet <vicente.botet@wanadoo.fr>:
Why a library will need a type nullptr_t while there is only a constant in C++11? Please coul you elaborate? According to draft of C++11 (I have no final version):
Pointer literals [lex.nullptr] pointer-literal:nullptr The pointer literal is the keyword `nullptr`. It is a prvalue of type `std::nullptr_t`. [ Note: `std::nullptr_t` is a distinct type that is neither a pointer type nor a pointer to member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value.
Oh, I see it now. Thanks, Vicente

Jeffrey Lee Hellrung, Jr.-2 wrote
On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <
eldiener@
>wrote:
I have found something like this to be helpful, when working with multiple compilers:
#include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif
where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed.
Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ?
+1.
Might it be better to just offer a (albeit imperfect) nullptr emulation if not supplied by the compiler? For example, [1].
[1] http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/nullptr
There are two levels that can be addressed by different approaches: * write portable code that uses C++11 nullptr when available and 0 otherwise. * write portable code that uses C++11 nullptr when available and something safer than 0 or NULL is used to represent a null pointer otherwise. The PO proposal corresponds to the first level, whilc IMO is already interesting. The more elaborated proposal corresponds to the second need. I will be for a direct inclusion of the BOOST_NULLPTR macro as part of the Boost.Config helpers, and why not accept a specific nullptr implementation if someone is ready to maintain it. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/config-Macro-for-null-pointer-tp4638690p4... Sent from the Boost - Dev mailing list archive at Nabble.com.

On 11/16/2012 12:32 AM, Jeffrey Lee Hellrung, Jr. wrote:
On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <eldiener@tropicsoft.com>wrote:
I have found something like this to be helpful, when working with multiple compilers:
#include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif
where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed.
Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ?
Might it be better to just offer a (albeit imperfect) nullptr emulation if not supplied by the compiler? For example, [1].
- Jeff
[1] http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/nullptr
I agree that you are right. If the nullptr emulation has less problems than using 0 it would seem worthwhile. That appears to be easily the case. Both are of course imperfect but it appears that a nullptr emulation is far less imperfect. The question then is who is going to do it and support it, given that it will most probably be obsolete in the near future as more compilers implement features of C++11. Unless someone steps up to do it ( and I am not that person due to, for one, already being behind in getting TTI into Boost ) it will not be done and then using 0 is at least a second best solution. In my own current use of nullptr in cross-compiler code for Boost using 0 is adequate for my means in the few instances where I am using nullptr. So my suggestion in my OP is adequate for me right now but may well not be adequate for others or for future usage on compilers which do not support nullptr.

On Sun, Nov 18, 2012 at 7:22 AM, Edward Diener <eldiener@tropicsoft.com>wrote:
On 11/16/2012 12:32 AM, Jeffrey Lee Hellrung, Jr. wrote:
On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <eldiener@tropicsoft.com>* *wrote:
I have found something like this to be helpful, when working with
multiple compilers:
#include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif
where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed.
Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ?
Might it be better to just offer a (albeit imperfect) nullptr emulation if not supplied by the compiler? For example, [1].
- Jeff
I agree that you are right.
If the nullptr emulation has less problems than using 0 it would seem worthwhile. That appears to be easily the case. Both are of course imperfect but it appears that a nullptr emulation is far less imperfect. The question then is who is going to do it and support it, given that it will most probably be obsolete in the near future as more compilers implement features of C++11. Unless someone steps up to do it ( and I am not that person due to, for one, already being behind in getting TTI into Boost ) it will not be done and then using 0 is at least a second best solution.
In my own current use of nullptr in cross-compiler code for Boost using 0 is adequate for my means in the few instances where I am using nullptr. So my suggestion in my OP is adequate for me right now but may well not be adequate for others or for future usage on compilers which do not support nullptr.
I'll post something this week and if it's ultimately decided to be included in, e.g., boost/utility, I don't have a problem supporting it. - Jeff

On Sun, Nov 18, 2012 at 2:03 PM, Jeffrey Lee Hellrung, Jr. < jeffrey.hellrung@gmail.com> wrote:
On Sun, Nov 18, 2012 at 7:22 AM, Edward Diener <eldiener@tropicsoft.com>wrote:
On 11/16/2012 12:32 AM, Jeffrey Lee Hellrung, Jr. wrote:
On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <eldiener@tropicsoft.com> **wrote:
I have found something like this to be helpful, when working with
multiple compilers:
#include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif
where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed.
Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ?
Might it be better to just offer a (albeit imperfect) nullptr emulation if not supplied by the compiler? For example, [1].
- Jeff
I agree that you are right.
If the nullptr emulation has less problems than using 0 it would seem worthwhile. That appears to be easily the case. Both are of course imperfect but it appears that a nullptr emulation is far less imperfect. The question then is who is going to do it and support it, given that it will most probably be obsolete in the near future as more compilers implement features of C++11. Unless someone steps up to do it ( and I am not that person due to, for one, already being behind in getting TTI into Boost ) it will not be done and then using 0 is at least a second best solution.
In my own current use of nullptr in cross-compiler code for Boost using 0 is adequate for my means in the few instances where I am using nullptr. So my suggestion in my OP is adequate for me right now but may well not be adequate for others or for future usage on compilers which do not support nullptr.
I'll post something this week and if it's ultimately decided to be included in, e.g., boost/utility, I don't have a problem supporting it.
First go at it: /*** BEGIN NULLPTR DEFINITION ***/ #include <boost/config.hpp> #ifndef BOOST_NO_NULLPTR #include <cstddef> namespace boost { typedef std::nullptr_t nullptr_t; } // namespace boost #else // #ifndef BOOST_NO_NULLPTR #include <ostream> namespace boost { struct nullptr_t { template< class T > operator T * () const { return static_cast< T * >(0); } template< class T, class C > operator T C:: * () const { return static_cast< T C:: * >(0); } #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS explicit operator bool () { return false; } #else // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS private: struct _boost_explicit_operator_bool_struct { }; typedef int (_boost_explicit_operator_bool_struct::*_boost_explicit_operator_bool_result_type); public: operator _boost_explicit_operator_bool_result_type () const { return 0; } #endif // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS // Must be public in order for nullptr_t to be POD. void * _boost_nullptr_sizeof; #ifndef BOOST_NO_DELETED_FUNCTIONS void operator & () const = delete; #else // #ifndef BOOST_NO_DELETED_FUNCTIONS private: void operator & () const; #endif // #ifndef BOOST_NO_DELETED_FUNCTIONS }; boost::nullptr_t const nullptr = { 0 }; inline bool operator==(boost::nullptr_t, boost::nullptr_t) { return true; } inline bool operator!=(boost::nullptr_t, boost::nullptr_t) { return false; } inline std::ostream & operator<<(std::ostream & o, boost::nullptr_t) { return o << static_cast< void * >(0); } } // namespace boost using boost::nullptr; #endif // #ifndef BOOST_NO_NULLPTR /*** END NULLPTR DEFINITION ***/ #include <cassert> #include <boost/implicit_cast.hpp> #include <boost/static_assert.hpp> struct X { }; int main(int argc, char * argv[]) { BOOST_STATIC_ASSERT( sizeof( nullptr ) == sizeof( void * ) ); assert(!static_cast< bool >(nullptr)); assert(!nullptr); assert(boost::implicit_cast< void * >(nullptr) == 0); assert(boost::implicit_cast< int * >(nullptr) == 0); assert(boost::implicit_cast< int X::* >(nullptr) == 0); //assert(nullptr == static_cast< void * >(0)); //assert(nullptr != &argc); return 0; } Unfortunately, the assertions that are commented out in main trigger an ICE on MSVC9 (yeah, big surprise); it's possible I did something wrong, but in the event that I didn't, if we can find a workaround to get such expressions to work, that'd be great (I tried explicitly defining operator== and operator!= out-of-line, and that didn't help). Also, I only tested this on MSVC9 (for now). Comments? - Jeff

On Wed, Nov 28, 2012 at 3:35 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
First go at it:
/*** BEGIN NULLPTR DEFINITION ***/
#include <boost/config.hpp>
#ifndef BOOST_NO_NULLPTR
I believe, the actual macros for C++11 features start with BOOST_NO_CXX11_ (e.g. BOOST_NO_CXX11_NULLPTR). The ones without CXX11 are deprecated.
#include <cstddef>
namespace boost {
typedef std::nullptr_t nullptr_t;
} // namespace boost
#else // #ifndef BOOST_NO_NULLPTR
#include <ostream>
<iosfwd>, please.
namespace boost {
struct nullptr_t { template< class T > operator T * () const { return static_cast< T * >(0); }
template< class T, class C > operator T C:: * () const { return static_cast< T C:: * >(0); }
#ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
explicit operator bool () { return false; }
#else // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
private: struct _boost_explicit_operator_bool_struct { }; typedef int (_boost_explicit_operator_bool_struct::*_boost_explicit_operator_bool_result_type); public: operator _boost_explicit_operator_bool_result_type () const { return 0; }
#endif // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
// Must be public in order for nullptr_t to be POD. void * _boost_nullptr_sizeof;
#ifndef BOOST_NO_DELETED_FUNCTIONS void operator & () const = delete; #else // #ifndef BOOST_NO_DELETED_FUNCTIONS private: void operator & () const; #endif // #ifndef BOOST_NO_DELETED_FUNCTIONS };
boost::nullptr_t const nullptr = { 0 };
inline bool operator==(boost::nullptr_t, boost::nullptr_t) { return true; } inline bool operator!=(boost::nullptr_t, boost::nullptr_t) { return false; }
inline std::ostream & operator<<(std::ostream & o, boost::nullptr_t) { return o << static_cast< void * >(0); }
I think, this is better: template< typename CharT, typename TraitsT > inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, boost::nullptr_t) { o << static_cast< void * >(0); return o; } It will also not require basic_ostream to be defined.
} // namespace boost
using boost::nullptr;
#endif // #ifndef BOOST_NO_NULLPTR
/*** END NULLPTR DEFINITION ***/
#include <cassert>
#include <boost/implicit_cast.hpp> #include <boost/static_assert.hpp>
struct X { };
int main(int argc, char * argv[]) { BOOST_STATIC_ASSERT( sizeof( nullptr ) == sizeof( void * ) ); assert(!static_cast< bool >(nullptr)); assert(!nullptr); assert(boost::implicit_cast< void * >(nullptr) == 0); assert(boost::implicit_cast< int * >(nullptr) == 0); assert(boost::implicit_cast< int X::* >(nullptr) == 0); //assert(nullptr == static_cast< void * >(0)); //assert(nullptr != &argc); return 0; }
Unfortunately, the assertions that are commented out in main trigger an ICE on MSVC9 (yeah, big surprise); it's possible I did something wrong, but in the event that I didn't, if we can find a workaround to get such expressions to work, that'd be great (I tried explicitly defining operator== and operator!= out-of-line, and that didn't help).
Will it help if you also define templated comparison operators with pointers?

On Nov 27, 2012, at 11:05 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
On Wed, Nov 28, 2012 at 3:35 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
First go at it:
/*** BEGIN NULLPTR DEFINITION ***/
#include <boost/config.hpp>
#ifndef BOOST_NO_NULLPTR
I believe, the actual macros for C++11 features start with BOOST_NO_CXX11_ (e.g. BOOST_NO_CXX11_NULLPTR). The ones without CXX11 are deprecated.
That is correct. See http://www.boost.org/doc/libs/1_52_0/libs/config/doc/html/boost_config/boost... for a complete list of deprecated macros and their replacements. -- Marshall

On Tue, Nov 27, 2012 at 11:05 PM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
On Wed, Nov 28, 2012 at 3:35 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
First go at it:
/*** BEGIN NULLPTR DEFINITION ***/
#include <boost/config.hpp>
#ifndef BOOST_NO_NULLPTR
I believe, the actual macros for C++11 features start with BOOST_NO_CXX11_ (e.g. BOOST_NO_CXX11_NULLPTR). The ones without CXX11 are deprecated.
Right, I just hadn't installed 1.52.0 yet; this macro transition seemed to be only halfway done in 1.51.0.
#include <cstddef>
namespace boost {
typedef std::nullptr_t nullptr_t;
} // namespace boost
#else // #ifndef BOOST_NO_NULLPTR
#include <ostream>
<iosfwd>, please.
Ah, need to overload on basic_ostream for that to work, of course.
namespace boost
{
struct nullptr_t { template< class T > operator T * () const { return static_cast< T * >(0); }
template< class T, class C > operator T C:: * () const { return static_cast< T C:: * >(0); }
#ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
explicit operator bool () { return false; }
#else // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
private: struct _boost_explicit_operator_bool_struct { }; typedef int
(_boost_explicit_operator_bool_struct::*_boost_explicit_operator_bool_result_type);
public: operator _boost_explicit_operator_bool_result_type () const { return 0; }
I guess this could be simplified slightly with just typedef (nullptr_t::*_boost_explicit_operator_bool_result_type);
#endif // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
// Must be public in order for nullptr_t to be POD. void * _boost_nullptr_sizeof;
#ifndef BOOST_NO_DELETED_FUNCTIONS void operator & () const = delete; #else // #ifndef BOOST_NO_DELETED_FUNCTIONS private: void operator & () const; #endif // #ifndef BOOST_NO_DELETED_FUNCTIONS };
boost::nullptr_t const nullptr = { 0 };
inline bool operator==(boost::nullptr_t, boost::nullptr_t) { return true; } inline bool operator!=(boost::nullptr_t, boost::nullptr_t) { return false; }
inline std::ostream & operator<<(std::ostream & o, boost::nullptr_t) { return o << static_cast< void * >(0); }
I think, this is better:
template< typename CharT, typename TraitsT > inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, boost::nullptr_t) { o << static_cast< void * >(0); return o; }
It will also not require basic_ostream to be defined.
Right.
} // namespace boost
using boost::nullptr;
#endif // #ifndef BOOST_NO_NULLPTR
/*** END NULLPTR DEFINITION ***/
#include <cassert>
#include <boost/implicit_cast.hpp> #include <boost/static_assert.hpp>
struct X { };
int main(int argc, char * argv[]) { BOOST_STATIC_ASSERT( sizeof( nullptr ) == sizeof( void * ) ); assert(!static_cast< bool >(nullptr)); assert(!nullptr); assert(boost::implicit_cast< void * >(nullptr) == 0); assert(boost::implicit_cast< int * >(nullptr) == 0); assert(boost::implicit_cast< int X::* >(nullptr) == 0); //assert(nullptr == static_cast< void * >(0)); //assert(nullptr != &argc); return 0; }
Unfortunately, the assertions that are commented out in main trigger an ICE on MSVC9 (yeah, big surprise); it's possible I did something wrong, but in the event that I didn't, if we can find a workaround to get such expressions to work, that'd be great (I tried explicitly defining operator== and operator!= out-of-line, and that didn't help).
Will it help if you also define templated comparison operators with pointers?
You mean template< class T > inline bool operator==(boost::nullptr_t, T * const p) { return 0 == p; } ? Yeah, no dice. - Jeff

On Wed, Nov 28, 2012 at 8:33 AM, Jeffrey Lee Hellrung, Jr. < jeffrey.hellrung@gmail.com> wrote:
On Tue, Nov 27, 2012 at 11:05 PM, Andrey Semashev < andrey.semashev@gmail.com> wrote:
On Wed, Nov 28, 2012 at 3:35 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
[...]
private: struct _boost_explicit_operator_bool_struct { }; typedef int
(_boost_explicit_operator_bool_struct::*_boost_explicit_operator_bool_result_type);
public: operator _boost_explicit_operator_bool_result_type () const { return 0; }
I guess this could be simplified slightly with just typedef (nullptr_t::*_boost_explicit_operator_bool_result_type); ---- And by that, I mean typedef int (nullptr_t::*_boost_explicit_operator_bool_result_type); - Jeff

On Tue, Nov 27, 2012 at 3:35 PM, Jeffrey Lee Hellrung, Jr. < jeffrey.hellrung@gmail.com> wrote: [...]
First go at it:
/*** BEGIN NULLPTR DEFINITION ***/
#include <boost/config.hpp>
#ifndef BOOST_NO_NULLPTR
#include <cstddef>
namespace boost {
typedef std::nullptr_t nullptr_t;
} // namespace boost
#else // #ifndef BOOST_NO_NULLPTR
[...]
using boost::nullptr;
One thing I wonder about is if this using declaration is The Right Thing To Do. An alternative is to provide a macro to bring the nullptr identifier into the current scope (and which does nothing in C++11).
#endif // #ifndef BOOST_NO_NULLPTR
[...] - Jeff

On Wed, Nov 28, 2012 at 8:43 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
using boost::nullptr;
One thing I wonder about is if this using declaration is The Right Thing To Do. An alternative is to provide a macro to bring the nullptr identifier into the current scope (and which does nothing in C++11).
I don't like the macro with using declaration. I'd rather have this using declaration in the header, with possibility to disable it by defining a config macro: #ifndef BOOST_NO_GLOBAL_NULLPTR using boost::nullptr; #endif And I want this declaration to be enabled by default since the language keyword is not scoped in a namespace and that's what we try to emulate. The macro switch is only there to solve problems if they arise.

On Wed, Nov 28, 2012 at 11:15 PM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
On Wed, Nov 28, 2012 at 8:43 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
using boost::nullptr;
One thing I wonder about is if this using declaration is The Right Thing To Do. An alternative is to provide a macro to bring the nullptr identifier into the current scope (and which does nothing in C++11).
I don't like the macro with using declaration. I'd rather have this using declaration in the header, with possibility to disable it by defining a config macro:
#ifndef BOOST_NO_GLOBAL_NULLPTR using boost::nullptr; #endif
And I want this declaration to be enabled by default since the language keyword is not scoped in a namespace and that's what we try to emulate. The macro switch is only there to solve problems if they arise.
Eh I don't think it's a good idea to control scope via a configuration macro. Anything that uses it unqualified (and which you have no control over) would suddenly break upon disabling the using declaration. In bringing this up, I'm thinking of the case in which some other 3rd party decided that they, too, wanted to provide a nullptr emulation, so now we have 2 conflicting nullptr identifiers at global scope. That makes Boost and this 3rd party library unusable together. - Jeff

On Thu, Nov 29, 2012 at 11:23 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Wed, Nov 28, 2012 at 11:15 PM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
On Wed, Nov 28, 2012 at 8:43 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
using boost::nullptr;
One thing I wonder about is if this using declaration is The Right Thing To Do. An alternative is to provide a macro to bring the nullptr identifier into the current scope (and which does nothing in C++11).
I don't like the macro with using declaration. I'd rather have this using declaration in the header, with possibility to disable it by defining a config macro:
#ifndef BOOST_NO_GLOBAL_NULLPTR using boost::nullptr; #endif
And I want this declaration to be enabled by default since the language keyword is not scoped in a namespace and that's what we try to emulate. The macro switch is only there to solve problems if they arise.
Eh I don't think it's a good idea to control scope via a configuration macro. Anything that uses it unqualified (and which you have no control over) would suddenly break upon disabling the using declaration.
You mean a third party library that relies on Boost emulation of nullptr? I think, the library has every mean to mitigate this problem (e.g. to check that nullptr is emulated and import it into its own namespace). There is no such problem with user's code as long as multiple libraries try to emulate global nullptr. If that happens you just disable all emulations but one. nullptr is still there, nothing breaks.
In bringing this up, I'm thinking of the case in which some other 3rd party decided that they, too, wanted to provide a nullptr emulation, so now we have 2 conflicting nullptr identifiers at global scope. That makes Boost and this 3rd party library unusable together.
That's exactly the reason the config macro is provided. Until such conflict appears one can safely use nullptr without qualification.

On Wed, Nov 28, 2012 at 11:32 PM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
On Thu, Nov 29, 2012 at 11:23 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Wed, Nov 28, 2012 at 11:15 PM, Andrey Semashev < andrey.semashev@gmail.com
wrote:
On Wed, Nov 28, 2012 at 8:43 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
using boost::nullptr;
One thing I wonder about is if this using declaration is The Right Thing To Do. An alternative is to provide a macro to bring the nullptr identifier into the current scope (and which does nothing in C++11).
I don't like the macro with using declaration. I'd rather have this using declaration in the header, with possibility to disable it by defining a config macro:
#ifndef BOOST_NO_GLOBAL_NULLPTR using boost::nullptr; #endif
And I want this declaration to be enabled by default since the language keyword is not scoped in a namespace and that's what we try to emulate. The macro switch is only there to solve problems if they arise.
Eh I don't think it's a good idea to control scope via a configuration macro. Anything that uses it unqualified (and which you have no control over) would suddenly break upon disabling the using declaration.
You mean a third party library that relies on Boost emulation of nullptr? I think, the library has every mean to mitigate this problem (e.g. to check that nullptr is emulated and import it into its own namespace).
Or even Boost code that may not be residing in the boost namespace. In any case, are you suggesting such code should have something along the lines of namespace X { #if !defined( BOOST_NO_CXX11_NULLPTR ) && !defined( BOOST_NO_GLOBAL_NULLPTR ) using boost::nullptr; #endif } ? That doesn't seem to be much of an improvement over a using macro :/ Actually...I'd go so far as to say it's objectively worse than a using macro. Note that Boost code residing in the boost namespace wouldn't need to qualify nullptr regardless of the presence/absence of the using declaration, so this is just concerns code outside the boost namespace which wishes to use the nullptr identifier. There is no such problem with user's code as long as multiple
libraries /don't/ try to emulate global nullptr. If that happens you just disable all emulations but one. nullptr is still there, nothing breaks.
Mildly annoying; and you hope all (or, at least, all but one) such emulated global nullptr's are responsible enough to have such a configuration macro :/ Strikes me as somewhat fragile.
In bringing this up, I'm thinking of the case in which some other 3rd party decided that they, too, wanted to provide a nullptr emulation, so now we have 2 conflicting nullptr identifiers at global scope. That makes Boost and this 3rd party library unusable together.
That's exactly the reason the config macro is provided. Until such conflict appears one can safely use nullptr without qualification.
That would be ideal but, as I've explained above, I still have some reservations about it. - Jeff

On Thu, Nov 29, 2012 at 11:47 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
Or even Boost code that may not be residing in the boost namespace. In any case, are you suggesting such code should have something along the lines of
namespace X {
#if !defined( BOOST_NO_CXX11_NULLPTR ) && !defined( BOOST_NO_GLOBAL_NULLPTR )
No, it's #if defined( BOOST_NO_CXX11_NULLPTR )
using boost::nullptr; #endif
}
?
That doesn't seem to be much of an improvement over a using macro :/ Actually...I'd go so far as to say it's objectively worse than a using macro.
Well, we could provide the using macro as well, although I don't think it's significantly better than the above. My main point is that nullptr should "just work" (tm) by default.
Note that Boost code residing in the boost namespace wouldn't need to qualify nullptr regardless of the presence/absence of the using declaration, so this is just concerns code outside the boost namespace which wishes to use the nullptr identifier.
That's right.
There is no such problem with user's code as long as multiple
libraries /don't/ try to emulate global nullptr. If that happens you just disable all emulations but one. nullptr is still there, nothing breaks.
Mildly annoying; and you hope all (or, at least, all but one) such emulated global nullptr's are responsible enough to have such a configuration macro :/ Strikes me as somewhat fragile.
Put it another way, are there any other emulations available yet? At this point the argument is mostly theoretical. And Boost will provide a way to disable its own global nullptr. If another library implements global nullptr that is inferior in some way and cannot be disabled, one has to pester that lib developers, not Boost.

On Thu, Nov 29, 2012 at 12:04 AM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
On Thu, Nov 29, 2012 at 11:47 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
Or even Boost code that may not be residing in the boost namespace. In
any
case, are you suggesting such code should have something along the lines of
namespace X {
#if !defined( BOOST_NO_CXX11_NULLPTR ) && !defined( BOOST_NO_GLOBAL_NULLPTR )
No, it's
#if defined( BOOST_NO_CXX11_NULLPTR )
Yes, you're correct.
using boost::nullptr; #endif
}
?
That doesn't seem to be much of an improvement over a using macro :/ Actually...I'd go so far as to say it's objectively worse than a using macro.
Well, we could provide the using macro as well, although I don't think it's significantly better than the above.
BOOST_USING_NULLPTR; Looks better to me :/ How much better is subjective. My main point is that
nullptr should "just work" (tm) by default.
But, it kinda doesn't "just work" if correct and robust use requires a conditional using declaration. And, at that point, what use is the "using boost::nullptr" at global scope anyway, if it's conditional on a configuration macro?
There is no such problem with user's code as long as multiple
libraries /don't/ try to emulate global nullptr. If that happens you just disable all emulations but one. nullptr is still there, nothing breaks.
Mildly annoying; and you hope all (or, at least, all but one) such emulated global nullptr's are responsible enough to have such a configuration macro :/ Strikes me as somewhat fragile.
Put it another way, are there any other emulations available yet? At this point the argument is mostly theoretical. And Boost will provide a way to disable its own global nullptr. If another library implements global nullptr that is inferior in some way and cannot be disabled, one has to pester that lib developers, not Boost.
True. - Jeff

On Thu, Nov 29, 2012 at 9:51 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 29, 2012 at 12:04 AM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
My main point is that nullptr should "just work" (tm) by default.
But, it kinda doesn't "just work" if correct and robust use requires a conditional using declaration. And, at that point, what use is the "using boost::nullptr" at global scope anyway, if it's conditional on a configuration macro?
The config macro is only used to solve problems, should they arise. Other than that nullptr will work after simply including the header. And I'm sure in 99.9% of cases this will be the case.

On Thu, Nov 29, 2012 at 10:59 PM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
On Thu, Nov 29, 2012 at 9:51 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 29, 2012 at 12:04 AM, Andrey Semashev < andrey.semashev@gmail.com
wrote:
My main point is that nullptr should "just work" (tm) by default.
But, it kinda doesn't "just work" if correct and robust use requires a conditional using declaration. And, at that point, what use is the "using boost::nullptr" at global scope anyway, if it's conditional on a configuration macro?
The config macro is only used to solve problems, should they arise. Other than that nullptr will work after simply including the header. And I'm sure in 99.9% of cases this will be the case.
Just to be clear, the conditional using declaration I was referring to is the one you suggested clients should use in their code, whereas you seem to be referring to the using declaration in the boost/utility/nullptr.hpp header. Is that right, and is my interpretation of your suggestion correct? - Jeff

On Fri, Nov 30, 2012 at 11:19 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 29, 2012 at 10:59 PM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
On Thu, Nov 29, 2012 at 9:51 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 29, 2012 at 12:04 AM, Andrey Semashev < andrey.semashev@gmail.com
wrote:
My main point is that nullptr should "just work" (tm) by default.
But, it kinda doesn't "just work" if correct and robust use requires a conditional using declaration. And, at that point, what use is the "using boost::nullptr" at global scope anyway, if it's conditional on a configuration macro?
The config macro is only used to solve problems, should they arise. Other than that nullptr will work after simply including the header. And I'm sure in 99.9% of cases this will be the case.
Just to be clear, the conditional using declaration I was referring to is the one you suggested clients should use in their code, whereas you seem to be referring to the using declaration in the boost/utility/nullptr.hpp header. Is that right, and is my interpretation of your suggestion correct?
Yes, I was referring to the global using declaration in boost/utility/nullptr.hpp and the BOOST_NO_GLOBAL_NULLPTR config macro. I have little concern about BOOST_USING_NULLPTR macro; I would probably use conditional using declaration in a public third party library anyway (I prefer explicitness of this solution).

On Fri, Nov 30, 2012 at 12:04 AM, Andrey Semashev <andrey.semashev@gmail.com
wrote:
On Fri, Nov 30, 2012 at 11:19 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 29, 2012 at 10:59 PM, Andrey Semashev < andrey.semashev@gmail.com
wrote:
On Thu, Nov 29, 2012 at 9:51 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 29, 2012 at 12:04 AM, Andrey Semashev < andrey.semashev@gmail.com
wrote:
My main point is that nullptr should "just work" (tm) by default.
But, it kinda doesn't "just work" if correct and robust use requires a conditional using declaration. And, at that point, what use is the "using boost::nullptr" at global scope anyway, if it's conditional on a configuration macro?
The config macro is only used to solve problems, should they arise. Other than that nullptr will work after simply including the header. And I'm sure in 99.9% of cases this will be the case.
Just to be clear, the conditional using declaration I was referring to is the one you suggested clients should use in their code, whereas you seem to be referring to the using declaration in the boost/utility/nullptr.hpp header. Is that right, and is my interpretation of your suggestion correct?
Yes, I was referring to the global using declaration in boost/utility/nullptr.hpp and the BOOST_NO_GLOBAL_NULLPTR config macro.
I have little concern about BOOST_USING_NULLPTR macro; I would probably use conditional using declaration in a public third party library anyway (I prefer explicitness of this solution).
Well either way, I reiterate my comment: If we have a conditional global-scope using declaration, I would imagine we would strongly recommend that client code likewise include a conditional using declaration (whether wrapped in a macro or explicitly expressed via #ifndef...#endif) so that things continue to "just work" whether the global-scope using declaration is enabled or not. On the other hand, requiring a user to just have a "BOOST_USING_NULLPTR;" declaration at the scope they wish to use the nullptr identifier seems safer (Boost doesn't inject anything into the global scope) and simpler / more uniform (no need for an additional configuration macro and explanation for why it's necessary and when one needs to concern oneself with it). - Jeff

On December 3, 2012 12:10:38 AM "Jeffrey Lee Hellrung, Jr." <jeffrey.hellrung@gmail.com> wrote:
Well either way, I reiterate my comment: If we have a conditional global-scope using declaration, I would imagine we would strongly recommend that client code likewise include a conditional using declaration (whether wrapped in a macro or explicitly expressed via #ifndef...#endif) so that things continue to "just work" whether the global-scope using declaration is enabled or not.
Why would I need the using declaration in my (user's) code if it's already provided by Boost header? I'm in control of my code, I know there are no conflicts and I do not disable the global nullptr provided by Boost. IMHO, you're trying to solve the problem that isn't there.
On the other hand, requiring a user to just have a "BOOST_USING_NULLPTR;" declaration at the scope they wish to use the nullptr identifier seems safer (Boost doesn't inject anything into the global scope) and simpler / more uniform (no need for an additional configuration macro and explanation for why it's necessary and when one needs to concern oneself with it).
I don't like macros. And for a small tool like nullptr including a header is just about as much as I would bother doing to get it. If I have to put BOOST_USING_NULLPTR in every place I intend to use nullptr I will probably be lazy enough to just continue using NULL. I would only recommend BOOST_USING_NULLPTR (or explicit conditional using declaration) to library writers, to avoid conflicts with other libraries. PS: And Boost does inject things into global scope already. At least _1, _2... come to mind.

On 12/2/2012 3:47 PM, Andrey Semashev wrote:
On December 3, 2012 12:10:38 AM "Jeffrey Lee Hellrung, Jr." <jeffrey.hellrung@gmail.com> wrote:
Well either way, I reiterate my comment: If we have a conditional global-scope using declaration, I would imagine we would strongly recommend that client code likewise include a conditional using declaration (whether wrapped in a macro or explicitly expressed via #ifndef...#endif) so that things continue to "just work" whether the global-scope using declaration is enabled or not.
Why would I need the using declaration in my (user's) code if it's already provided by Boost header? I'm in control of my code, I know there are no conflicts and I do not disable the global nullptr provided by Boost. IMHO, you're trying to solve the problem that isn't there.
On the other hand, requiring a user to just have a "BOOST_USING_NULLPTR;" declaration at the scope they wish to use the nullptr identifier seems safer (Boost doesn't inject anything into the global scope) and simpler / more uniform (no need for an additional configuration macro and explanation for why it's necessary and when one needs to concern oneself with it).
I don't like macros. And for a small tool like nullptr including a header is just about as much as I would bother doing to get it. If I have to put BOOST_USING_NULLPTR in every place I intend to use nullptr I will probably be lazy enough to just continue using NULL.
I do like macros but I agree with what you say above from a usability point of view.
I would only recommend BOOST_USING_NULLPTR (or explicit conditional using declaration) to library writers, to avoid conflicts with other libraries.
PS: And Boost does inject things into global scope already. At least _1, _2... come to mind.
That is a mistake that should not have been made and has been the subject of numerous posts already when conflicts occured between various libraries using the _1, _2 notation. But I do agree with you in this case that specifying 'nullptr' should just work without the end-user having to do anything but include a boost header file, which supports the Boost 'nullptr' implementation. The reason I feel this way in the current situation is because 'nullptr' as a C++ keyword and therefore is 'global' to everything. Once the correct header is included the Boost nullptr should be as transparently as possible like the C++ 'nullptr' without the user having to do anything more. A macro should be created to turn off the use of the Boost nullptr as a substitute for the C++ 'nullptr' when the C++ implementation does not support the 'nullptr' keyword.

On Sun, Dec 2, 2012 at 8:23 PM, Edward Diener <eldiener@tropicsoft.com>wrote:
On 12/2/2012 3:47 PM, Andrey Semashev wrote:
On December 3, 2012 12:10:38 AM "Jeffrey Lee Hellrung, Jr." <jeffrey.hellrung@gmail.com> wrote:
Well either way, I reiterate my comment: If we have a conditional global-scope using declaration, I would imagine we would strongly recommend that client code likewise include a conditional using declaration (whether wrapped in a macro or explicitly expressed via #ifndef...#endif) so that things continue to "just work" whether the global-scope using declaration is enabled or not.
Why would I need the using declaration in my (user's) code if it's already provided by Boost header? I'm in control of my code, I know there are no conflicts and I do not disable the global nullptr provided by Boost. IMHO, you're trying to solve the problem that isn't there.
On the other hand, requiring a user to just have a "BOOST_USING_NULLPTR;"
declaration at the scope they wish to use the nullptr identifier seems safer (Boost doesn't inject anything into the global scope) and simpler / more uniform (no need for an additional configuration macro and explanation for why it's necessary and when one needs to concern oneself with it).
I don't like macros. And for a small tool like nullptr including a header is just about as much as I would bother doing to get it. If I have to put BOOST_USING_NULLPTR in every place I intend to use nullptr I will probably be lazy enough to just continue using NULL.
I do like macros but I agree with what you say above from a usability point of view.
There's nothing wrong with macros; just like everything in C++, they can be used to great benefit and abused to great...the opposite of benefit.
I would only recommend BOOST_USING_NULLPTR (or explicit conditional
using declaration) to library writers, to avoid conflicts with other libraries.
PS: And Boost does inject things into global scope already. At least _1, _2... come to mind.
That is a mistake that should not have been made and has been the subject of numerous posts already when conflicts occured between various libraries using the _1, _2 notation.
Yeah, sorry Andrey, this only serves to reinforce my hesitation toward injecting identifiers into the global namespace :) But I do agree with you in this case that specifying 'nullptr' should just
work without the end-user having to do anything but include a boost header file, which supports the Boost 'nullptr' implementation. The reason I feel this way in the current situation is because 'nullptr' as a C++ keyword and therefore is 'global' to everything. Once the correct header is included the Boost nullptr should be as transparently as possible like the C++ 'nullptr' without the user having to do anything more.
I sympathize with this. I just prefer to be conservative if the costs are not great. I think this is where we disagree.
A macro should be created to turn off the use of the Boost nullptr as a substitute for the C++ 'nullptr' when the C++ implementation does not support the 'nullptr' keyword.
Well I guess unless anyone speaks up opposed to globally injecting nullptr into the global namespace, that's what I'll do (as I'm outvoted :) Conditional on non-definition of a macro, of course. - Jeff

On 12/4/2012 10:06 AM, Jeffrey Lee Hellrung, Jr. wrote:
Well I guess unless anyone speaks up opposed to globally injecting nullptr into the global namespace, that's what I'll do (as I'm outvoted :) Conditional on non-definition of a macro, of course.
Please, no. The bind placeholders are bad enough. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 12/4/2012 1:10 PM, Eric Niebler wrote:
On 12/4/2012 10:06 AM, Jeffrey Lee Hellrung, Jr. wrote:
Well I guess unless anyone speaks up opposed to globally injecting nullptr into the global namespace, that's what I'll do (as I'm outvoted :) Conditional on non-definition of a macro, of course.
Please, no. The bind placeholders are bad enough.
The use of 'nullptr' is "global" in C++. Why should not the inclusion of a particular Boost header file, possibly emulating 'nullptr' for compilers that do not support it, also create a "global" 'nullptr'. I totally agree that normally injecting anything into the global namespace is a very poor thing to do. But in this case we would be emulating something that is already "global" by the C++ standard. The idea I believe is this: the end-user includes the Boost header file. If there is already an implementation of 'nullptr' for the particular C++ compiler beng used, absolutely nothing in the header file does anything. If there is not an implementation of 'nullptr' for the particular C++ compiler beng used, the end-user's use of 'nullptr' in his code is using the Boost implementation. Expecting an end-user to both include the Boost header file and then somehow know or care whether or not his compiler supports 'nullptr' and do something more when it does not before he can use 'nullptr' in his code, seems to me to defeat the purpose of providing a nullptr emulation.

On 12/4/2012 12:05 PM, Edward Diener wrote:
On 12/4/2012 1:10 PM, Eric Niebler wrote:
On 12/4/2012 10:06 AM, Jeffrey Lee Hellrung, Jr. wrote:
Well I guess unless anyone speaks up opposed to globally injecting nullptr into the global namespace, that's what I'll do (as I'm outvoted :) Conditional on non-definition of a macro, of course.
Please, no. The bind placeholders are bad enough.
The use of 'nullptr' is "global" in C++. Why should not the inclusion of a particular Boost header file, possibly emulating 'nullptr' for compilers that do not support it, also create a "global" 'nullptr'.
I totally agree that normally injecting anything into the global namespace is a very poor thing to do. But in this case we would be emulating something that is already "global" by the C++ standard.
The idea I believe is this: the end-user includes the Boost header file. If there is already an implementation of 'nullptr' for the particular C++ compiler beng used, absolutely nothing in the header file does anything. If there is not an implementation of 'nullptr' for the particular C++ compiler beng used, the end-user's use of 'nullptr' in his code is using the Boost implementation.
Expecting an end-user to both include the Boost header file and then somehow know or care whether or not his compiler supports 'nullptr' and do something more when it does not before he can use 'nullptr' in his code, seems to me to defeat the purpose of providing a nullptr emulation.
... until some other library ALSO defines a global nullptr symbol, making that library and boost mutually incompatible. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Tue, Dec 4, 2012 at 2:14 PM, Peter Dimov <lists@pdimov.com> wrote:
Eric Niebler wrote:
... until some other library ALSO defines a global nullptr symbol, making that library and boost mutually incompatible.
How is the end user supposed to actually use nullptr if it's not global? It's a keyword in C++11; boost::nullptr is not legal.
namespace X { BOOST_USING_NULLPTR; void foo() { int * p = nullptr; } } // namespace X is the basic usage I had proposed. BOOST_USING_NULLPTR expands to some empty statement in C++11 and "using ::boost::nullptr" in C++03. - Jeff

On 12/4/2012 2:21 PM, Jeffrey Lee Hellrung, Jr. wrote:
On Tue, Dec 4, 2012 at 2:14 PM, Peter Dimov <lists@pdimov.com> wrote:
Eric Niebler wrote:
... until some other library ALSO defines a global nullptr symbol, making that library and boost mutually incompatible.
How is the end user supposed to actually use nullptr if it's not global? It's a keyword in C++11; boost::nullptr is not legal.
namespace X {
BOOST_USING_NULLPTR;
void foo() { int * p = nullptr; }
} // namespace X
is the basic usage I had proposed. BOOST_USING_NULLPTR expands to some empty statement in C++11 and "using ::boost::nullptr" in C++03.
Right. In my understanding, it could work like this: // Some stupid lib does this: constexpr struct mynullptr_t {} mynullptr {}; // Boost does this: namespace boost { constexpr struct mynullptr_t {} mynullptr {}; } #define BOOST_USING_NULLPTR \ using boost::mynullptr_t; \ using boost::mynullptr // Third-party code does this: namespace my { BOOST_USING_NULLPTR; void foo() { mynullptr_t x; x = mynullptr; } } No ambiguity. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 12/4/2012 3:19 PM, Eric Niebler wrote:
On 12/4/2012 12:05 PM, Edward Diener wrote:
On 12/4/2012 1:10 PM, Eric Niebler wrote:
On 12/4/2012 10:06 AM, Jeffrey Lee Hellrung, Jr. wrote:
Well I guess unless anyone speaks up opposed to globally injecting nullptr into the global namespace, that's what I'll do (as I'm outvoted :) Conditional on non-definition of a macro, of course.
Please, no. The bind placeholders are bad enough.
The use of 'nullptr' is "global" in C++. Why should not the inclusion of a particular Boost header file, possibly emulating 'nullptr' for compilers that do not support it, also create a "global" 'nullptr'.
I totally agree that normally injecting anything into the global namespace is a very poor thing to do. But in this case we would be emulating something that is already "global" by the C++ standard.
The idea I believe is this: the end-user includes the Boost header file. If there is already an implementation of 'nullptr' for the particular C++ compiler beng used, absolutely nothing in the header file does anything. If there is not an implementation of 'nullptr' for the particular C++ compiler beng used, the end-user's use of 'nullptr' in his code is using the Boost implementation.
Expecting an end-user to both include the Boost header file and then somehow know or care whether or not his compiler supports 'nullptr' and do something more when it does not before he can use 'nullptr' in his code, seems to me to defeat the purpose of providing a nullptr emulation.
... until some other library ALSO defines a global nullptr symbol, making that library and boost mutually incompatible.
I doubt that the case will occur very often. But in that case the end-user will have to choose which nullptr emulation to use. If he chooses the other library's emulation he does not include the Boost header file for nullptr emulation, and vice-versa. Anything more complicated than that, where he wants to choose which nullptr implemenetation to use after including both library's header files, is utterly unrealistic to me.

On 12/4/2012 2:46 PM, Edward Diener wrote:
But in that case the end-user will have to choose which nullptr emulation to use. If he chooses the other library's emulation he does not include the Boost header file for nullptr emulation, and vice-versa.
We've learned the hard way that that doesn't work in practice. User wants to use libraries X and Y. X uses Boost.Nullptr and doesn't compiler without it. Y defines its own nullptr. Boom. Please don't ignore the lessons of the past. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On December 5, 2012 12:19:36 AM Eric Niebler <eric@boostpro.com> wrote:
On 12/4/2012 12:05 PM, Edward Diener wrote:
Expecting an end-user to both include the Boost header file and then somehow know or care whether or not his compiler supports 'nullptr' and do something more when it does not before he can use 'nullptr' in his code, seems to me to defeat the purpose of providing a nullptr emulation.
... until some other library ALSO defines a global nullptr symbol, making that library and boost mutually incompatible.
The global nullptr in the Boost header is going to be conditional on a config macro. You just disable it in this (rare) case and the problem is solved.

On 12/4/2012 7:16 PM, Andrey Semashev wrote:
On December 5, 2012 12:19:36 AM Eric Niebler <eric@boostpro.com> wrote:
On 12/4/2012 12:05 PM, Edward Diener wrote:
Expecting an end-user to both include the Boost header file and then somehow know or care whether or not his compiler supports 'nullptr' and do something more when it does not before he can use 'nullptr' in his code, seems to me to defeat the purpose of providing a nullptr
emulation.
... until some other library ALSO defines a global nullptr symbol, making that library and boost mutually incompatible.
The global nullptr in the Boost header is going to be conditional on a config macro. You just disable it in this (rare) case and the problem is solved.
... and Microsoft's min/max macros cause no problems because they can be disabled with NOMINMAX. :-P -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Tue, Dec 4, 2012 at 11:13 PM, Eric Niebler <eric@boostpro.com> wrote:
On 12/4/2012 7:16 PM, Andrey Semashev wrote:
On December 5, 2012 12:19:36 AM Eric Niebler <eric@boostpro.com> wrote:
On 12/4/2012 12:05 PM, Edward Diener wrote:
Expecting an end-user to both include the Boost header file and then somehow know or care whether or not his compiler supports 'nullptr' and do something more when it does not before he can use 'nullptr' in his code, seems to me to defeat the purpose of providing a nullptr
emulation.
... until some other library ALSO defines a global nullptr symbol, making that library and boost mutually incompatible.
The global nullptr in the Boost header is going to be conditional on a config macro. You just disable it in this (rare) case and the problem is solved.
... and Microsoft's min/max macros cause no problems because they can be disabled with NOMINMAX. :-P
Haha, yes good point. As much as it sucks, we'll be stuck with 0 for some time. Doesn't suck that much actually. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Wed, Dec 5, 2012 at 11:13 AM, Eric Niebler <eric@boostpro.com> wrote:
On 12/4/2012 7:16 PM, Andrey Semashev wrote:
On December 5, 2012 12:19:36 AM Eric Niebler <eric@boostpro.com> wrote:
On 12/4/2012 12:05 PM, Edward Diener wrote:
Expecting an end-user to both include the Boost header file and then somehow know or care whether or not his compiler supports 'nullptr' and do something more when it does not before he can use 'nullptr' in his code, seems to me to defeat the purpose of providing a nullptr
emulation.
... until some other library ALSO defines a global nullptr symbol, making that library and boost mutually incompatible.
The global nullptr in the Boost header is going to be conditional on a config macro. You just disable it in this (rare) case and the problem is solved.
... 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.

On Wed, Dec 5, 2012 at 5:22 AM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
On Wed, Dec 5, 2012 at 11:13 AM, Eric Niebler <eric@boostpro.com> 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. []'s -- Felipe Magno de Almeida

On December 5, 2012 3:32:05 PM Felipe Magno de Almeida <felipe.m.almeida@gmail.com> wrote:
On Wed, Dec 5, 2012 at 5:22 AM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
On Wed, Dec 5, 2012 at 11:13 AM, Eric Niebler <eric@boostpro.com> 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?

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? 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. Nate

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

On December 5, 2012 10:50:41 PM Eric Niebler <eric@boostpro.com> wrote:
On 12/5/2012 8:59 AM, Nathan Crookston wrote:
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.
Are you suggesting that Boost may not work when Boost's global nullptr is disabled? I find it unlikely to happen because unqualified nullptr from boost namespace will always bind to boost::nullptr regardless of the global using declaration. Even if it does happen somehow, we will fix it. This may happen if a third-party lib doesn't use BOOST_USING_NULLPTR to import nullptr to its namespace and uses unqualified nullptr. That would be a bug in that library then.
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
If the alternative is to always use BOOST_USING_NULLPTR, I would probably agree, except that I would use NULL instead of 0.

On Wed, Dec 5, 2012 at 12:16 PM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
On December 5, 2012 10:50:41 PM Eric Niebler <eric@boostpro.com> wrote:
[...]
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
If the alternative is to always use BOOST_USING_NULLPTR, I would probably agree, except that I would use NULL instead of 0.
At that point, might as well use boost::nullptr (or whatever you want to call it) instead of either NULL or 0. Or, as Nathan suggested, drop trying to emulate the literal nullptr keyword and just define and use boost::nullptr_. That's probably the best option. Slightly uglier, but no macros and no name collisions. - Jeff

On Thu, Dec 6, 2012 at 7:42 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
Or, as Nathan suggested, drop trying to emulate the literal nullptr keyword and just define and use boost::nullptr_. That's probably the best option. Slightly uglier, but no macros and no name collisions.
Nathan's code sample has an error, it always uses boost::detail::nullptr_t to define nullptr_. After correcting this I'm not sure that the following: namespace boost { typedef std::nullptr_t nullptr_t; const nullptr_t nullptr_ = {}; } is valid and supposed to work. If I'm not mistaken, we know almost nothing about std::nullptr_t. In particular, we don't know if it's default constructible and if it is, will it be equivalent to nullptr. Also, boost::nullptr is supposed to help writing C++11-style code even for C++03 compilers. With a different keyword that doesn't hold anymore, a migration path is needed. I'm not sure it's worth the effort in this case.

Andrey Semashev wrote:
On Thu, Dec 6, 2012 at 7:42 AM, Jeffrey Lee Hellrung, Jr. wrote:
Or, as Nathan suggested, drop trying to emulate the literal nullptr
keyword
and just define and use boost::nullptr_. That's probably the best option. Slightly uglier, but no macros and no name collisions.
Nathan's code sample has an error, it always uses boost::detail::nullptr_t to define nullptr_. After correcting this I'm not sure that the following:
namespace boost {
typedef std::nullptr_t nullptr_t; const nullptr_t nullptr_ = {};
}
is valid and supposed to work. If I'm not mistaken, we know almost nothing about std::nullptr_t. In particular, we don't know if it's default constructible and if it is, will it be equivalent to nullptr.
The particular initialization of the previous may not be legal, but from the standard it appears that contructing std::nullptr_t should work. This post [1] seems to agree with my reading (and it has references).
Also, boost::nullptr is supposed to help writing C++11-style code even for C++03 compilers. With a different keyword that doesn't hold anymore, a migration path is needed. I'm not sure it's worth the effort in this case.
True. It would be nice if there was *something* which was implicitly convertible to a null shared_ptr<T> (regardless of T) -- that's the biggest place I miss nullptr in my current code. Construction from boost::none is a really nice usability feature of boost::optional. Thanks, Nate [1] < http://stackoverflow.com/questions/9953068/is-nullptr-t-a-default-constructi...

On Wed, Dec 5, 2012 at 10:10 PM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
On Thu, Dec 6, 2012 at 7:42 AM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
Or, as Nathan suggested, drop trying to emulate the literal nullptr
keyword
and just define and use boost::nullptr_. That's probably the best option. Slightly uglier, but no macros and no name collisions.
Nathan's code sample has an error, it always uses boost::detail::nullptr_t to define nullptr_. After correcting this I'm
not sure that the following:
namespace boost {
typedef std::nullptr_t nullptr_t; const nullptr_t nullptr_ = {};
}
is valid and supposed to work. If I'm not mistaken, we know almost nothing about std::nullptr_t. In particular, we don't know if it's default constructible and if it is, will it be equivalent to nullptr.
Also, boost::nullptr is supposed to help writing C++11-style code even for C++03 compilers. With a different keyword that doesn't hold anymore, a migration path is needed. I'm not sure it's worth the effort in this case.
Well, I think some individuals here (I'd put myself in that camp) are opposed to injecting anything into the global namespace if it can be helped, and here it certainly can be helped. So if we add a nullptr emulation in Boost, it's going to have to be paired with a using macro, a different name (i.e., boost::nullptr_), or both. If no one will use this utility given the latter imperfections, I'm fine with just dropping the proposal altogether and everyone can go back to using NULL or C++11. - Jeff

Well, I think some individuals here (I'd put myself in that camp) are opposed to injecting anything into the global namespace if it can be helped, and here it certainly can be helped. So if we add a nullptr emulation in Boost, it's going to have to be paired with a using macro, a different name (i.e., boost::nullptr_), or both. If no one will use this utility given the latter imperfections, I'm fine with just dropping the proposal altogether and everyone can go back to using NULL or C++11. Just to put in my vote for not putting anything in the global namespace but providing a "BOOST_USING_NULLPTR" macro. We keep our nullptr emulation in our library namespace too and would gladly switch to a boost one.
For use cases, distributed libraries that have a namespace can just use the macro to pull nullptr into their namespace and non-distributed libraries or executables without namespace can safely use the macro to pull it into the global namespace (since they know their environment). This is, in general, one line of code for the whole project if you stick it in the config header. The only problematic case are distributed C++ libraries that don't have a namespace. But I'm fine making those do more awkward things as it is bad practice and, I think, not that common any more. --Daniel

On Dec 7, 2012, at 12:14 PM, Daniel Russel <drussel@gmail.com> wrote:
Well, I think some individuals here (I'd put myself in that camp) are opposed to injecting anything into the global namespace if it can be helped, and here it certainly can be helped. So if we add a nullptr emulation in Boost, it's going to have to be paired with a using macro, a different name (i.e., boost::nullptr_), or both. If no one will use this utility given the latter imperfections, I'm fine with just dropping the proposal altogether and everyone can go back to using NULL or C++11. Just to put in my vote for not putting anything in the global namespace but providing a "BOOST_USING_NULLPTR" macro. We keep our nullptr emulation in our library namespace too and would gladly switch to a boost one.
We've already got: BOOST_NO_CXX11_NULLPTR http://www.boost.org/doc/libs/1_52_0/libs/config/doc/html/boost_config/boost... -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Fri, Dec 7, 2012 at 1:54 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
On Dec 7, 2012, at 12:14 PM, Daniel Russel <drussel@gmail.com> wrote:
Well, I think some individuals here (I'd put myself in that camp) are opposed to injecting anything into the global namespace if it can be helped, and here it certainly can be helped. So if we add a nullptr emulation in Boost, it's going to have to be paired with a using macro,
a
different name (i.e., boost::nullptr_), or both. If no one will use this utility given the latter imperfections, I'm fine with just dropping the proposal altogether and everyone can go back to using NULL or C++11. Just to put in my vote for not putting anything in the global namespace but providing a "BOOST_USING_NULLPTR" macro. We keep our nullptr emulation in our library namespace too and would gladly switch to a boost one.
We've already got: BOOST_NO_CXX11_NULLPTR
http://www.boost.org/doc/libs/1_52_0/libs/config/doc/html/boost_config/boost...
Yes, the definition of BOOST_USING_NULLPTR depends on whether BOOST_NO_CXX11_NULLPTR is defined :) It's just a convenience macro equivalent to #ifndef BOOST_NO_CX11_NULLPTR using ::boost::nullptr; #endif - Jeff

On Dec 7, 2012, at 2:06 PM, "Jeffrey Lee Hellrung, Jr." <jeffrey.hellrung@gmail.com> wrote:
On Fri, Dec 7, 2012 at 1:54 PM, Marshall Clow <mclow.lists@gmail.com> wrote:
On Dec 7, 2012, at 12:14 PM, Daniel Russel <drussel@gmail.com> wrote:
Well, I think some individuals here (I'd put myself in that camp) are opposed to injecting anything into the global namespace if it can be helped, and here it certainly can be helped. So if we add a nullptr emulation in Boost, it's going to have to be paired with a using macro,
a
different name (i.e., boost::nullptr_), or both. If no one will use this utility given the latter imperfections, I'm fine with just dropping the proposal altogether and everyone can go back to using NULL or C++11. Just to put in my vote for not putting anything in the global namespace but providing a "BOOST_USING_NULLPTR" macro. We keep our nullptr emulation in our library namespace too and would gladly switch to a boost one.
We've already got: BOOST_NO_CXX11_NULLPTR
http://www.boost.org/doc/libs/1_52_0/libs/config/doc/html/boost_config/boost...
Yes, the definition of BOOST_USING_NULLPTR depends on whether BOOST_NO_CXX11_NULLPTR is defined :) It's just a convenience macro equivalent to
#ifndef BOOST_NO_CX11_NULLPTR using ::boost::nullptr; #endif
That was what I wanted to be sure of; that we didn't introduce (yet) another config macro when we already had one. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Fri, Dec 7, 2012 at 12:14 PM, Daniel Russel <drussel@gmail.com> wrote:
Well, I think some individuals here (I'd put myself in that camp) are opposed to injecting anything into the global namespace if it can be helped, and here it certainly can be helped. So if we add a nullptr emulation in Boost, it's going to have to be paired with a using macro, a different name (i.e., boost::nullptr_), or both. If no one will use this utility given the latter imperfections, I'm fine with just dropping the proposal altogether and everyone can go back to using NULL or C++11. Just to put in my vote for not putting anything in the global namespace but providing a "BOOST_USING_NULLPTR" macro. We keep our nullptr emulation in our library namespace too and would gladly switch to a boost one.
Good to know. For use cases, distributed libraries that have a namespace can just use the
macro to pull nullptr into their namespace and non-distributed libraries or executables without namespace can safely use the macro to pull it into the global namespace (since they know their environment). This is, in general, one line of code for the whole project if you stick it in the config header. The only problematic case are distributed C++ libraries that don't have a namespace. But I'm fine making those do more awkward things as it is bad practice and, I think, not that common any more. --Daniel
That's a good point... - Jeff

On Wed, Dec 5, 2012 at 4:43 AM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
On December 5, 2012 3:32:05 PM Felipe Magno de Almeida < felipe.m.almeida@gmail.com> wrote:
On Wed, Dec 5, 2012 at 5:22 AM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
On Wed, Dec 5, 2012 at 11:13 AM, Eric Niebler <eric@boostpro.com> 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 think the argument is that it's inconvenient when things do break. Much more inconvenient (and potentially less obvious to diagnose) than the inconvenience associated with requiring the user to explicitly bring the nullptr identifier into their desired use scope each time (which, IMHO, is not so bad). When you determine that you now need to disable the global nullptr using declaration that Boost provides, the situation could potentially require you to fix up all your nullptr uses to ensure you have a BOOST_USING_NULLPTR declaration in the proper scopes (e.g., header X begins to use library Y, which (perhaps irresponsibly) provides a ::nullptr that conflicts with Boost's, so now everything that directly or indirectly includes header X and uses nullptr needs a BOOST_USING_NULLPTR => PITA). - Jeff

On December 5, 2012 10:15:23 PM "Jeffrey Lee Hellrung, Jr." <jeffrey.hellrung@gmail.com> wrote:
I think the argument is that it's inconvenient when things do break. Much more inconvenient (and potentially less obvious to diagnose) than the inconvenience associated with requiring the user to explicitly bring the nullptr identifier into their desired use scope each time (which, IMHO, is not so bad).
I guess that's where our views differ. I prefer normal usage to be as straightforward as possible. OTOH, it is acceptable for problem solving to require some additional effort.

Le 29/11/12 08:23, Jeffrey Lee Hellrung, Jr. a écrit :
On Wed, Nov 28, 2012 at 11:15 PM, Andrey Semashev <andrey.semashev@gmail.com
wrote: On Wed, Nov 28, 2012 at 8:43 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
using boost::nullptr;
One thing I wonder about is if this using declaration is The Right Thing To Do. An alternative is to provide a macro to bring the nullptr identifier into the current scope (and which does nothing in C++11). I don't like the macro with using declaration. I'd rather have this using declaration in the header, with possibility to disable it by defining a config macro:
#ifndef BOOST_NO_GLOBAL_NULLPTR using boost::nullptr; #endif
And I want this declaration to be enabled by default since the language keyword is not scoped in a namespace and that's what we try to emulate. The macro switch is only there to solve problems if they arise.
Eh I don't think it's a good idea to control scope via a configuration macro. Anything that uses it unqualified (and which you have no control over) would suddenly break upon disabling the using declaration.
How the using declaration would help if a 3pp library provides already nullptr in the global namespace? This will be ambiguous, isn't it?
In bringing this up, I'm thinking of the case in which some other 3rd party decided that they, too, wanted to provide a nullptr emulation, so now we have 2 conflicting nullptr identifiers at global scope. That makes Boost and this 3rd party library unusable together.
The macro to disable the using declaration makes them usable together, but the problem is that now code that was using the bool emulation will use the 3pp one. I don't think there is a global solution to this problem. I think that the library should provide the using declaration by default so a user that knows that his application would not have any 3pp trouble could use the unqualified nullptr. Unfortunately libraries authors including Boost libraries should use nullptr qualified as ::boost::nullptr to avoid any possible conflicts. Vicente

On Thu, Nov 29, 2012 at 10:40 AM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Le 29/11/12 08:23, Jeffrey Lee Hellrung, Jr. a écrit :
On Wed, Nov 28, 2012 at 11:15 PM, Andrey Semashev < andrey.semashev@gmail.com
wrote: On Wed, Nov 28, 2012 at 8:43 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
using boost::nullptr;
One thing I wonder about is if this using declaration is The Right
Thing
To
Do. An alternative is to provide a macro to bring the nullptr identifier into the current scope (and which does nothing in C++11).
I don't like the macro with using declaration. I'd rather have this using declaration in the header, with possibility to disable it by defining a config macro:
#ifndef BOOST_NO_GLOBAL_NULLPTR using boost::nullptr; #endif
And I want this declaration to be enabled by default since the language keyword is not scoped in a namespace and that's what we try to emulate. The macro switch is only there to solve problems if they arise.
Eh I don't think it's a good idea to control scope via a configuration macro. Anything that uses it unqualified (and which you have no control over) would suddenly break upon disabling the using declaration.
How the using declaration would help if a 3pp library provides already nullptr in the global namespace?
The using declaration above is presumed to reside in some namespace or function.
This will be ambiguous, isn't it?
In bringing this up, I'm thinking of the case in which some other 3rd party decided that they, too, wanted to provide a nullptr emulation, so now we have 2 conflicting nullptr identifiers at global scope. That makes Boost and this 3rd party library unusable together.
The macro to disable the using declaration makes them usable together,
but the problem is that now code that was using the bool emulation will use the 3pp one.
Actually, yeah, that could be problematic...
I don't think there is a global solution to this problem. I think that the library should provide the using declaration by default so a user that knows that his application would not have any 3pp trouble could use the unqualified nullptr. Unfortunately libraries authors including Boost libraries should use nullptr qualified as ::boost::nullptr to avoid any possible conflicts.
Well, I don't know if that's possible, as ::boost::nullptr would probably trigger a compiler error when the real nullptr is present. I'm leaning toward being conservative and just provide a using macro. Then one only has to state the macro once within each file they use nullptr (doesn't seem like that big a deal) and they can use it unqualified thereafter. If the using declaration is anywhere except global scope, there shouldn't ever be conflicts from any other (reasonable) nullptr emulations. E.g., use would be something like namespace X { BOOST_USING_NULLPTR; void f() { int * p = nullptr; } } // namespace X - Jeff

On Thu, Nov 29, 2012 at 10:40 PM, Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> wrote:
Unfortunately libraries authors including Boost libraries should use nullptr qualified as ::boost::nullptr to avoid any possible conflicts.
Not Boost authors, unqualified nullptr will refer to boost::nullptr.
participants (16)
-
Andrey Semashev
-
Andrzej Krzemienski
-
Antony Polukhin
-
Daniel Russel
-
Edward Diener
-
Emil Dotchevski
-
Eric Niebler
-
Felipe Magno de Almeida
-
Jeffrey Lee Hellrung, Jr.
-
Jookia
-
Marshall Clow
-
Matt Calabrese
-
Nathan Crookston
-
Peter Dimov
-
Vicente Botet
-
Vicente J. Botet Escriba