Another patch for long long in gcc -std=c++98

This is a followup from prior threads: TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC in type_traits/is_convertable.hpp: http://thread.gmane.org/gmane.comp.lib.boost.devel/106708 long long support with GCC: http://thread.gmane.org/gmane.comp.lib.boost.user/6693 The following patch is another attempt to get long long support working, in a manner acceptable with Boost, even when -std=c++98 and -pedantic are specified. In particular, GCC supports long long in all modes, but __extension__ is required to quiet errors and warnings. It is possible that other C++ compilers with a similar situation regarding long long might be able to use this patch constructively. In short, typedefs are added for long long and unsigned long long in cstdint.hpp, and all uses of these typenames in the headers are changed to use these new names. Aaron W. LaFramboise Index: boost/boost/cast.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/cast.hpp,v retrieving revision 1.22 diff -c -p -r1.22 cast.hpp *** boost/boost/cast.hpp 11 Aug 2004 10:59:33 -0000 1.22 --- boost/boost/cast.hpp 15 Aug 2004 08:25:07 -0000 *************** *** 45,50 **** --- 45,51 ---- # include <boost/config.hpp> # include <cassert> # include <typeinfo> + # include <boost/cstdint.hpp> # include <boost/type.hpp> # include <boost/limits.hpp> # include <boost/detail/select_type.hpp> *************** namespace boost *** 156,166 **** // long / unsigned long long. Not intended to be full // numeric_limits replacements, but good enough for numeric_cast<> template <> ! struct fixed_numeric_limits_base<long long, false> { BOOST_STATIC_CONSTANT(bool, is_specialized = true); BOOST_STATIC_CONSTANT(bool, is_signed = true); ! static long long max BOOST_PREVENT_MACRO_SUBSTITUTION () { # ifdef LONGLONG_MAX return LONGLONG_MAX; --- 157,167 ---- // long / unsigned long long. Not intended to be full // numeric_limits replacements, but good enough for numeric_cast<> template <> ! struct fixed_numeric_limits_base<longlong, false> { BOOST_STATIC_CONSTANT(bool, is_specialized = true); BOOST_STATIC_CONSTANT(bool, is_signed = true); ! static longlong max BOOST_PREVENT_MACRO_SUBSTITUTION () { # ifdef LONGLONG_MAX return LONGLONG_MAX; *************** namespace boost *** 169,175 **** # endif } ! static long long min BOOST_PREVENT_MACRO_SUBSTITUTION () { # ifdef LONGLONG_MIN return LONGLONG_MIN; --- 170,176 ---- # endif } ! static longlong min BOOST_PREVENT_MACRO_SUBSTITUTION () { # ifdef LONGLONG_MIN return LONGLONG_MIN; *************** namespace boost *** 180,190 **** }; template <> ! struct fixed_numeric_limits_base<unsigned long long, false> { BOOST_STATIC_CONSTANT(bool, is_specialized = true); BOOST_STATIC_CONSTANT(bool, is_signed = false); ! static unsigned long long max BOOST_PREVENT_MACRO_SUBSTITUTION () { # ifdef ULONGLONG_MAX return ULONGLONG_MAX; --- 181,191 ---- }; template <> ! struct fixed_numeric_limits_base<ulonglong, false> { BOOST_STATIC_CONSTANT(bool, is_specialized = true); BOOST_STATIC_CONSTANT(bool, is_signed = false); ! static ulonglong max BOOST_PREVENT_MACRO_SUBSTITUTION () { # ifdef ULONGLONG_MAX return ULONGLONG_MAX; *************** namespace boost *** 193,199 **** # endif } ! static unsigned long long min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; } }; # endif } // namespace detail --- 194,200 ---- # endif } ! static ulonglong min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; } }; # endif } // namespace detail Index: boost/boost/concept_check.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/concept_check.hpp,v retrieving revision 1.28 diff -c -p -r1.28 concept_check.hpp *** boost/boost/concept_check.hpp 26 Jul 2004 00:31:58 -0000 1.28 --- boost/boost/concept_check.hpp 15 Aug 2004 08:25:10 -0000 *************** *** 16,21 **** --- 16,22 ---- #define BOOST_CONCEPT_CHECKS_HPP #include <boost/config.hpp> + #include <boost/cstdint.hpp> #include <boost/iterator.hpp> #include <boost/type_traits/conversion_traits.hpp> #include <utility> *************** struct require_same { typedef T type; }; *** 179,185 **** template <> struct SignedIntegerConcept<int> { void constraints() {} }; template <> struct SignedIntegerConcept<long> { void constraints() {} }; # if defined(BOOST_HAS_LONG_LONG) ! template <> struct SignedIntegerConcept<long long> { void constraints() {} }; # endif // etc. #endif --- 180,186 ---- template <> struct SignedIntegerConcept<int> { void constraints() {} }; template <> struct SignedIntegerConcept<long> { void constraints() {} }; # if defined(BOOST_HAS_LONG_LONG) ! template <> struct SignedIntegerConcept<longlong> { void constraints() {} }; # endif // etc. #endif Index: boost/boost/cstdint.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/cstdint.hpp,v retrieving revision 1.33 diff -c -p -r1.33 cstdint.hpp *** boost/boost/cstdint.hpp 10 Aug 2004 12:53:33 -0000 1.33 --- boost/boost/cstdint.hpp 15 Aug 2004 08:25:11 -0000 *************** namespace boost *** 278,283 **** --- 278,305 ---- #endif // BOOST_HAS_STDINT_H + + #ifdef BOOST_HAS_LONG_LONG + + namespace boost { + + # ifdef __GNUC__ + + __extension__ typedef long long longlong; + __extension__ typedef unsigned long long ulonglong; + + # else + + typedef long long longlong; + typedef unsigned long long ulonglong; + + # endif + + } // namespace boost + + # endif // BOOST_HAS_LONG_LONG + + #endif // BOOST_CSTDINT_HPP Index: boost/boost/integer_fwd.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/integer_fwd.hpp,v retrieving revision 1.3 diff -c -p -r1.3 integer_fwd.hpp *** boost/boost/integer_fwd.hpp 11 Aug 2004 10:59:33 -0000 1.3 --- boost/boost/integer_fwd.hpp 15 Aug 2004 08:25:11 -0000 *************** *** 12,19 **** #include <climits> // for UCHAR_MAX, etc. #include <cstddef> // for std::size_t ! #include <boost/config.hpp> // for BOOST_NO_INTRINSIC_WCHAR_T ! #include <boost/limits.hpp> // for std::numeric_limits namespace boost --- 12,20 ---- #include <climits> // for UCHAR_MAX, etc. #include <cstddef> // for std::size_t ! #include <boost/config.hpp> // for BOOST_NO_INTRINSIC_WCHAR_T ! #include <boost/cstdint.hpp> // for longlong ! #include <boost/limits.hpp> // for std::numeric_limits namespace boost *************** template < > *** 67,76 **** #ifdef ULLONG_MAX template < > ! class integer_traits< long long >; template < > ! class integer_traits< unsigned long long >; #endif --- 68,77 ---- #ifdef ULLONG_MAX template < > ! class integer_traits< longlong >; template < > ! class integer_traits< ulonglong >; #endif Index: boost/boost/limits.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/limits.hpp,v retrieving revision 1.11 diff -c -p -r1.11 limits.hpp *** boost/boost/limits.hpp 10 Aug 2004 12:53:33 -0000 1.11 --- boost/boost/limits.hpp 15 Aug 2004 08:25:12 -0000 *************** *** 12,17 **** --- 12,18 ---- #define BOOST_LIMITS #include <boost/config.hpp> + #include <boost/cstdint.hpp> #ifdef BOOST_NO_LIMITS # include <boost/detail/limits.hpp> *************** *** 25,31 **** #ifdef BOOST_HAS_MS_INT64 # define BOOST_LLT __int64 #else ! # define BOOST_LLT long long #endif namespace std --- 26,32 ---- #ifdef BOOST_HAS_MS_INT64 # define BOOST_LLT __int64 #else ! # define BOOST_LLT longlong #endif namespace std Index: boost/boost/iterator/counting_iterator.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/iterator/counting_iterator.hpp,v retrieving revision 1.5 diff -c -p -r1.5 counting_iterator.hpp *** boost/boost/iterator/counting_iterator.hpp 26 Jul 2004 00:31:59 -0000 1.5 --- boost/boost/iterator/counting_iterator.hpp 15 Aug 2004 08:25:14 -0000 *************** *** 6,11 **** --- 6,12 ---- # define COUNTING_ITERATOR_DWA200348_HPP # include <boost/iterator/iterator_adaptor.hpp> + # include <boost/cstdint.hpp> # include <boost/detail/numeric_traits.hpp> # include <boost/mpl/bool.hpp> # include <boost/mpl/if.hpp> *************** namespace detail *** 57,67 **** # if defined(BOOST_HAS_LONG_LONG) template <> ! struct is_numeric<long long> : mpl::true_ {}; template <> ! struct is_numeric<unsigned long long> : mpl::true_ {}; # endif --- 58,68 ---- # if defined(BOOST_HAS_LONG_LONG) template <> ! struct is_numeric<longlong> : mpl::true_ {}; template <> ! struct is_numeric<ulonglong> : mpl::true_ {}; # endif Index: boost/boost/numeric/interval/detail/ppc_rounding_control.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/numeric/interval/detail/ppc_rounding_control.hpp,v retrieving revision 1.3 diff -c -p -r1.3 ppc_rounding_control.hpp *** boost/boost/numeric/interval/detail/ppc_rounding_control.hpp 19 Jul 2004 21:38:06 -0000 1.3 --- boost/boost/numeric/interval/detail/ppc_rounding_control.hpp 15 Aug 2004 08:25:18 -0000 *************** namespace interval_lib { *** 25,31 **** namespace detail { typedef union { ! long long int imode; double dmode; } rounding_mode_struct; --- 25,31 ---- namespace detail { typedef union { ! __extension__ long long int imode; double dmode; } rounding_mode_struct; Index: boost/boost/python/type_id.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/python/type_id.hpp,v retrieving revision 1.15 diff -c -p -r1.15 type_id.hpp *** boost/boost/python/type_id.hpp 26 Jul 2004 00:32:05 -0000 1.15 --- boost/boost/python/type_id.hpp 15 Aug 2004 08:25:20 -0000 *************** *** 11,16 **** --- 11,17 ---- # include <boost/operators.hpp> # include <typeinfo> # include <cstring> + # include <boost/cstdint.hpp> # include <boost/static_assert.hpp> # include <boost/detail/workaround.hpp> # include <boost/type_traits/same_traits.hpp> *************** BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(lon *** 100,106 **** // using Python's macro instead of Boost's - we don't seem to get the // config right all the time. # ifdef HAVE_LONG_LONG ! BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long) # endif # undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID # endif --- 101,107 ---- // using Python's macro instead of Boost's - we don't seem to get the // config right all the time. # ifdef HAVE_LONG_LONG ! BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(longlong) # endif # undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID # endif Index: boost/boost/python/detail/wrap_python.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/python/detail/wrap_python.hpp,v retrieving revision 1.18 diff -c -p -r1.18 wrap_python.hpp *** boost/boost/python/detail/wrap_python.hpp 26 Jul 2004 00:32:07 -0000 1.18 --- boost/boost/python/detail/wrap_python.hpp 15 Aug 2004 08:25:21 -0000 *************** *** 25,30 **** --- 25,31 ---- // which confuses Boost's config // #include <limits.h> + #include <boost/cstdint.hpp> #ifndef ULONG_MAX # define BOOST_PYTHON_ULONG_MAX_UNDEFINED #endif *************** typedef int pid_t; *** 86,92 **** # endif # define HAVE_LONG_LONG 1 ! # define LONG_LONG long long # endif # elif defined(__MWERKS__) --- 87,93 ---- # endif # define HAVE_LONG_LONG 1 ! # define LONG_LONG longlong # endif # elif defined(__MWERKS__) Index: boost/boost/spirit/phoenix/operators.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/spirit/phoenix/operators.hpp,v retrieving revision 1.7 diff -c -p -r1.7 operators.hpp *** boost/boost/spirit/phoenix/operators.hpp 28 Jul 2004 01:57:45 -0000 1.7 --- boost/boost/spirit/phoenix/operators.hpp 15 Aug 2004 08:25:27 -0000 *************** *** 23,28 **** --- 23,29 ---- #include <boost/spirit/phoenix/actor.hpp> #include <boost/spirit/phoenix/composite.hpp> #include <boost/config.hpp> + #include <boost/cstdint.hpp> /////////////////////////////////////////////////////////////////////////////// namespace phoenix { *************** template <> struct rank<long> *** 373,380 **** template <> struct rank<unsigned long> { static int const value = 100; }; #ifdef BOOST_HAS_LONG_LONG ! template <> struct rank<long long> { static int const value = 110; }; ! template <> struct rank<unsigned long long> { static int const value = 120; }; #endif template <> struct rank<float> { static int const value = 130; }; --- 374,381 ---- template <> struct rank<unsigned long> { static int const value = 100; }; #ifdef BOOST_HAS_LONG_LONG ! template <> struct rank<boost::longlong> { static int const value = 110; }; ! template <> struct rank<boost::ulonglong> { static int const value = 120; }; #endif template <> struct rank<float> { static int const value = 130; }; Index: boost/boost/spirit/utility/chset.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/spirit/utility/chset.hpp,v retrieving revision 1.6 diff -c -p -r1.6 chset.hpp *** boost/boost/spirit/utility/chset.hpp 9 Jul 2004 08:28:06 -0000 1.6 --- boost/boost/spirit/utility/chset.hpp 15 Aug 2004 08:25:27 -0000 *************** *** 14,19 **** --- 14,20 ---- #include <boost/shared_ptr.hpp> #include <boost/spirit/core/primitives/primitives.hpp> #include <boost/spirit/utility/impl/chset/basic_chset.hpp> + #include <boost/cstdint.hpp> /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { *************** chset_p(unsigned long ch) *** 164,177 **** #ifdef BOOST_HAS_LONG_LONG ////////////////////////////////// ! inline chset<long long> ! chset_p(long long ch) ! { return chset<long long>(ch); } ////////////////////////////////// ! inline chset<unsigned long long> ! chset_p(unsigned long long ch) ! { return chset<unsigned long long>(ch); } #endif /////////////////////////////////////////////////////////////////////////////// --- 165,178 ---- #ifdef BOOST_HAS_LONG_LONG ////////////////////////////////// ! inline chset<longlong> ! chset_p(longlong ch) ! { return chset<longlong>(ch); } ////////////////////////////////// ! inline chset<ulonglong> ! chset_p(ulonglong ch) ! { return chset<ulonglong>(ch); } #endif /////////////////////////////////////////////////////////////////////////////// Index: boost/boost/type_traits/is_convertible.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/type_traits/is_convertible.hpp,v retrieving revision 1.25 diff -c -p -r1.25 is_convertible.hpp *** boost/boost/type_traits/is_convertible.hpp 6 Jan 2004 13:37:10 -0000 1.25 --- boost/boost/type_traits/is_convertible.hpp 15 Aug 2004 08:25:29 -0000 *************** *** 22,27 **** --- 22,29 ---- # include "boost/type_traits/is_void.hpp" #endif + #include "boost/cstdint.hpp" + // should be always the last #include directive #include "boost/type_traits/detail/bool_trait_def.hpp" *************** BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_converti *** 260,266 **** TT_AUX_IS_CONVERTIBLE_SPEC_2(F,short) \ TT_AUX_IS_CONVERTIBLE_SPEC_2(F,int) \ TT_AUX_IS_CONVERTIBLE_SPEC_2(F,long) \ ! TT_AUX_IS_CONVERTIBLE_SPEC_2(F,long long) \ /**/ # define TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(F) \ --- 262,269 ---- TT_AUX_IS_CONVERTIBLE_SPEC_2(F,short) \ TT_AUX_IS_CONVERTIBLE_SPEC_2(F,int) \ TT_AUX_IS_CONVERTIBLE_SPEC_2(F,long) \ ! TT_AUX_IS_CONVERTIBLE_SPEC(F,longlong) \ ! TT_AUX_IS_CONVERTIBLE_SPEC(F,ulonglong) \ /**/ # define TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(F) \ Index: boost/boost/type_traits/is_integral.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/type_traits/is_integral.hpp,v retrieving revision 1.8 diff -c -p -r1.8 is_integral.hpp *** boost/boost/type_traits/is_integral.hpp 1 May 2004 10:32:58 -0000 1.8 --- boost/boost/type_traits/is_integral.hpp 15 Aug 2004 08:25:29 -0000 *************** *** 10,15 **** --- 10,16 ---- #define BOOST_TT_IS_INTEGRAL_HPP_INCLUDED #include "boost/config.hpp" + #include "boost/cstdint.hpp" // should be the last #include #include "boost/type_traits/detail/bool_trait_def.hpp" *************** BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_inte *** 57,64 **** #endif # if defined(BOOST_HAS_LONG_LONG) ! BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,unsigned long long,true) ! BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,long long,true) #elif defined(BOOST_HAS_MS_INT64) BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,unsigned __int64,true) BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,__int64,true) --- 58,65 ---- #endif # if defined(BOOST_HAS_LONG_LONG) ! BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,ulonglong,true) ! BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,longlong,true) #elif defined(BOOST_HAS_MS_INT64) BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,unsigned __int64,true) BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,__int64,true) Index: boost/boost/type_traits/type_with_alignment.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/type_traits/type_with_alignment.hpp,v retrieving revision 1.24 diff -c -p -r1.24 type_with_alignment.hpp *** boost/boost/type_traits/type_with_alignment.hpp 26 Jan 2004 12:20:03 -0000 1.24 --- boost/boost/type_traits/type_with_alignment.hpp 15 Aug 2004 08:25:30 -0000 *************** *** 8,13 **** --- 8,14 ---- #ifndef BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED #define BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED + #include "boost/cstdint.hpp" #include "boost/mpl/if.hpp" #include "boost/preprocessor/list/for_each_i.hpp" #include "boost/preprocessor/tuple/to_list.hpp" *************** typedef int (alignment_dummy::*member_fu *** 43,49 **** #ifdef BOOST_HAS_LONG_LONG #define BOOST_TT_ALIGNMENT_BASE_TYPES BOOST_PP_TUPLE_TO_LIST( \ 12, ( \ ! char, short, int, long, long long, float, double, long double \ , void*, function_ptr, member_ptr, member_function_ptr)) #else #define BOOST_TT_ALIGNMENT_BASE_TYPES BOOST_PP_TUPLE_TO_LIST( \ --- 44,50 ---- #ifdef BOOST_HAS_LONG_LONG #define BOOST_TT_ALIGNMENT_BASE_TYPES BOOST_PP_TUPLE_TO_LIST( \ 12, ( \ ! char, short, int, long, longlong, float, double, long double \ , void*, function_ptr, member_ptr, member_function_ptr)) #else #define BOOST_TT_ALIGNMENT_BASE_TYPES BOOST_PP_TUPLE_TO_LIST( \

"Aaron W. LaFramboise" <aaronrabiddog51@aaronwl.com> writes:
This is a followup from prior threads: TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC in type_traits/is_convertable.hpp: http://thread.gmane.org/gmane.comp.lib.boost.devel/106708 long long support with GCC: http://thread.gmane.org/gmane.comp.lib.boost.user/6693
The following patch is another attempt to get long long support working, in a manner acceptable with Boost, even when -std=c++98 and -pedantic are specified. In particular, GCC supports long long in all modes, but __extension__ is required to quiet errors and warnings.
It is possible that other C++ compilers with a similar situation regarding long long might be able to use this patch constructively.
In short, typedefs are added for long long and unsigned long long in cstdint.hpp, and all uses of these typenames in the headers are changed to use these new names.
On naming, I think long_long and unsigned_long_long might be better, but I don't have a strong position here. The patch is essentially OK with me, but it touches a number of other peoples' libraries so we maybe should hear from others, and it will require some labor to commit. Should we give Aaron CVS access for this? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

On Aug 15, 2004, at 11:32 AM, David Abrahams wrote:
The patch is essentially OK with me, but it touches a number of other peoples' libraries so we maybe should hear from others, and it will require some labor to commit. Should we give Aaron CVS access for this?
The patch looks okay to me and yes, we should give Aaron CVS access to make this change. Doug

Doug Gregor <dgregor@cs.indiana.edu> writes:
On Aug 15, 2004, at 11:32 AM, David Abrahams wrote:
The patch is essentially OK with me, but it touches a number of other peoples' libraries so we maybe should hear from others, and it will require some labor to commit. Should we give Aaron CVS access for this?
The patch looks okay to me and yes, we should give Aaron CVS access to make this change.
Did you just volunteer? ;-) -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

On 8/15/04 12:32 PM, "David Abrahams" <dave@boost-consulting.com> wrote:
"Aaron W. LaFramboise" <aaronrabiddog51@aaronwl.com> writes:
This is a followup from prior threads: TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC in type_traits/is_convertable.hpp: http://thread.gmane.org/gmane.comp.lib.boost.devel/106708 long long support with GCC: http://thread.gmane.org/gmane.comp.lib.boost.user/6693
The following patch is another attempt to get long long support working, in a manner acceptable with Boost, even when -std=c++98 and -pedantic are specified. In particular, GCC supports long long in all modes, but __extension__ is required to quiet errors and warnings.
It is possible that other C++ compilers with a similar situation regarding long long might be able to use this patch constructively.
In short, typedefs are added for long long and unsigned long long in cstdint.hpp, and all uses of these typenames in the headers are changed to use these new names.
On naming, I think long_long and unsigned_long_long might be better, but I don't have a strong position here.
I don't understand what problem this change is going to solve. If a compiler has a strict C++-1998 mode, then supporting "(unsigned) long long" anyway is sort-of a disfeature. Maybe we should just have the headers assume that the double-long types are absent. (The changes don't affect compilers that don't have the double-long types at all, right?)
The patch is essentially OK with me, but it touches a number of other peoples' libraries so we maybe should hear from others, and it will require some labor to commit. Should we give Aaron CVS access for this?
-- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com

Daryle Walker wrote:
I don't understand what problem this change is going to solve. If a compiler has a strict C++-1998 mode, then supporting "(unsigned) long long" anyway is sort-of a disfeature. Maybe we should just have the headers assume that the double-long types are absent. (The changes don't affect compilers that don't have the double-long types at all, right?)
The -std=c++98 option (also called -ansi) causes gcc to become standards compliant. Without it, gcc implements a nonstandard "GNU" dialect of C++. People who desire standards conformance and better compile-time checking often use this option. For many C++ projects, all files are compiled with it along with the more familiar -Wall. As a side effect, it causes errors to be generated when the long long typename is used unadorned. (I've heard this might be changed in the future, as long long might not actually conflict with the standard.) All of the support is still there, including from the standard library. You can still use long long provided you add __extension__, as documented in the manual. To further clarify, -std=c++98 does not disable long long, and in general, does not disable extensions. It just means you need to use a special syntax when you use the long long type name. So, to answer your question, this patch makes Boost compile for people who use the very common practice of compiling with -std=c++98 (or -pedantic). While it would be possible to just disable long long support on GCC -std=c++98 is specified (and not support -pedantic at all), this would be very unfortunate, as this type is still supported in this mode, and users still expect it to work correctly and be supported by libraries. -std= Documentation: http://gcc.gnu.org/onlinedocs/gcc-3.4.1/gcc/C-Dialect-Options.html long long in libstdc++: http://gcc.gnu.org/onlinedocs/libstdc++/configopts.html Aaron W. LaFramboise

On Tue, Aug 17, 2004 at 06:25:30AM -0500, Aaron W. LaFramboise wrote:
Daryle Walker wrote:
I don't understand what problem this change is going to solve. If a compiler has a strict C++-1998 mode, then supporting "(unsigned) long long" anyway is sort-of a disfeature. Maybe we should just have the headers assume that the double-long types are absent. (The changes don't affect compilers that don't have the double-long types at all, right?)
The -std=c++98 option (also called -ansi) causes gcc to become standards compliant. Without it, gcc implements a nonstandard "GNU" dialect of C++. People who desire standards conformance and better compile-time checking often use this option. For many C++ projects, all files are compiled with it along with the more familiar -Wall.
As a side effect, it causes errors to be generated when the long long typename is used unadorned.
This isn't strictly true. "long long" will be accepted without any diagnostic, even with "-ansi -Wall", it is "-pedantic" that causes it to be rejected. I tested this on Linux and FreeBSD, with 2.95 and 3.[0345], and the doc links you gave confirm it: The -ansi option does not cause non-ISO programs to be rejected gratuitously. For that, -pedantic is required in addition to -ansi. See Warning Options.
(I've heard this might be changed in the future, as long long might not actually conflict with the standard.) All of the support is still there, including from the standard library. You can still use long long provided you add __extension__, as documented in the manual.
To further clarify, -std=c++98 does not disable long long, and in general, does not disable extensions. It just means you need to use a special syntax when you use the long long type name.
To further clarify, it's -pedantic that means you need __extension__, with or without -std=c++98 / -ansi
So, to answer your question, this patch makes Boost compile for people who use the very common practice of compiling with -std=c++98 (or -pedantic).
This should read "... practice of compiling with -pedantic." jon -- "Any sufficiently advanced bug is indistinguishable from a feature" - Rich Kulawiec

As a side effect, it causes errors to be generated when the long long typename is used unadorned.
This isn't strictly true. "long long" will be accepted without any diagnostic, even with "-ansi -Wall", it is "-pedantic" that causes it to be rejected. I tested this on Linux and FreeBSD, with 2.95 and 3.[0345], and the doc links you gave confirm it:
That's right, and if you supply -Wno-long-long as well, then you can compile with -pedantic -ansi -Wall with no problems. John.

John Maddock wrote:
As a side effect, it causes errors to be generated when the long long typename is used unadorned.
This isn't strictly true. "long long" will be accepted without any diagnostic, even with "-ansi -Wall", it is "-pedantic" that causes it to be rejected. I tested this on Linux and FreeBSD, with 2.95 and 3.[0345], and the doc links you gave confirm it:
That's right, and if you supply -Wno-long-long as well, then you can compile with -pedantic -ansi -Wall with no problems.
I don't know why I had assumed that this had something to do with -std=c++98 rather than -pedantic. Sorry for the misinformation. Despite these comments, I still beleive that it is valuable to allow Boost to compile cleanly with -pedantic without having to specify -Wno-long-long. In the name of encapsulation, the main program/project should not have to disable warnings (that the developers may well be interested in) because the implementation of a library might need the warning disabled to compile cleanly. The reason to reject this sort of patch would be that changing all instances of long long in headers would be too intrusive. Given that long long is not yet standardized in any C++ standard, I do not think that it is inappropriate to access it through a proxy type name, and that it would be valuable to allow Boost to work seamlessly with GCC diverse option sets (and possibly other compilers that have a similar situation). Is there a policy or rationale on modifying Boost code to eliminate compiler warnings? Since I do not want to use -pedantic but not specify -Wno-longlong--I really do want the 'pedantic' warnings with unadorned extensions like long long warned--it is likely that I (and perhaps many other people who use GCC) will retain something like this patch locally if it is deemed inappropriate for Boost. This would be unfortunate. Aaron W. LaFramboise

Since I do not want to use -pedantic but not specify -Wno-longlong--I really do want the 'pedantic' warnings with unadorned extensions like long long warned--it is likely that I (and perhaps many other people who use GCC) will retain something like this patch locally if it is deemed inappropriate for Boost. This would be unfortunate.
How about something like: BOOST_EXTENSION(x) which expands to "__extension__ x" on gcc and "x" otherwise? Then we can use BOOST_EXTENSION(long long) where necessary. Thoughts? John.

On Wed, Aug 18, 2004 at 12:37:44PM +0100, John Maddock wrote:
Since I do not want to use -pedantic but not specify -Wno-longlong--I really do want the 'pedantic' warnings with unadorned extensions like long long warned--it is likely that I (and perhaps many other people who use GCC) will retain something like this patch locally if it is deemed inappropriate for Boost. This would be unfortunate.
I certainly think it makes sense to do something to allow compiling with -pedantic. Since -std=c++98 has little effect on g++ (at least until C++0x exists and is supported) it's possible (I won't claim likely) that -pedantic is more commonly used, as it has a real and noticeable effect.
How about something like:
BOOST_EXTENSION(x)
which expands to "__extension__ x" on gcc and "x" otherwise?
Then we can use BOOST_EXTENSION(long long) where necessary.
Thoughts?
I like that. It's obvious that you're talking about the commonly available "long long" type, and also obvious it's an extension. Aaron's long_long type _could_ mean something other than "long long" The __extension__ keyword can be used before any expression that -pedantic rejects, including literals such as 0LL or 0ULL, so that macro would make that BOOST_EXTENSION( 0LL ). jon -- "It is useless to attempt to reason a man out of a thing he was never reasoned into." - Jonathan Swift

John Maddock wrote:
How about something like:
BOOST_EXTENSION(x)
which expands to "__extension__ x" on gcc and "x" otherwise?
Then we can use BOOST_EXTENSION(long long) where necessary.
This is what I initially tried to do. However, it is difficult to make work. Consider: template<typename T> class myclass { }; __extension__ template<> class myclass<long long> { }; Note the placement of __extension__. This is the only place that __extension__ can be placed that it will make the error go away, and not trigger a parse error. Simply prefixing "long long" with __extension__ does not, in general, work. With complicated source lines, the placement of __extension__ may be entirely non-obvious. It is possible, for certain constructs, that there is no appropriate way that __extension__ might be added. In fact, the documentation is not clear on exactly how __extension__ is supposed to be placed, as (in my reading) its description does not correspond with actual usage: http://gcc.gnu.org/onlinedocs/gcc-3.4.1/gcc/Alternate-Keywords.html Using __extension__ at each instance of long long would require anyone using long long in Boost headers to know particular characteristics of GCC in this regard, which I think is unacceptable. I think a typedef is the only way to shield the rest of Boost from this issue. Aaron W. LaFramboise

This is what I initially tried to do. However, it is difficult to make work.
Consider:
template<typename T> class myclass { }; __extension__ template<> class myclass<long long> { };
Note the placement of __extension__. This is the only place that __extension__ can be placed that it will make the error go away, and not trigger a parse error.
Simply prefixing "long long" with __extension__ does not, in general, work. With complicated source lines, the placement of __extension__ may be entirely non-obvious. It is possible, for certain constructs, that there is no appropriate way that __extension__ might be added. In fact, the documentation is not clear on exactly how __extension__ is supposed to be placed, as (in my reading) its description does not correspond with actual usage: http://gcc.gnu.org/onlinedocs/gcc-3.4.1/gcc/Alternate-Keywords.html
Using __extension__ at each instance of long long would require anyone using long long in Boost headers to know particular characteristics of GCC in this regard, which I think is unacceptable. I think a typedef is the only way to shield the rest of Boost from this issue.
OK, understood. John.

Aaron W. LaFramboise wrote:
The following patch is another attempt to get long long support working, in a manner acceptable with Boost, even when -std=c++98 and -pedantic are specified. In particular, GCC supports long long in all modes, but __extension__ is required to quiet errors and warnings.
I think all disccused issues were resolved. What is the status on this? Aaron W. LaFramboise

Aaron W. LaFramboise wrote:
The following patch is another attempt to get long long support working, in a manner acceptable with Boost, even when -std=c++98 and -pedantic are specified. In particular, GCC supports long long in all modes, but __extension__ is required to quiet errors and warnings.
I think all disccused issues were resolved. What is the status on this?
I'll try and commit some patches this week, if no-one objects I'll use: namespace boost{ __extension__ typedef long long long_long_type; __extension__ typedef unsigned long long ulong_long_type; } Inside the config system (since all the headers include that anyway). The replace [unsigned] long long with the fully qualified names (::boost::long_long_type etc). John.

John Maddock wrote:
I'll try and commit some patches this week, if no-one objects I'll use:
Thanks. FYI, TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC in type_traits/is_convertible.hpp needs a slightly less mechanical change: - TT_AUX_IS_CONVERTIBLE_SPEC_2(F,long long) \ + TT_AUX_IS_CONVERTIBLE_SPEC(F,long_long_type) \ + TT_AUX_IS_CONVERTIBLE_SPEC(F,ulong_long_type) \ Aaron W. LaFramboise

Changes are now in cvs: as a result almost all of boost's test can be compiled with -pedantic -ansi with gcc. The changes have been tested with gcc 3.3 and 2.95, VC7.1 and Intel 8, so hopefully there won't be any fallout, but if there is, shout :-) John.
participants (6)
-
Aaron W. LaFramboise
-
Daryle Walker
-
David Abrahams
-
Doug Gregor
-
John Maddock
-
Jonathan Wakely