This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: More test results...



> xxx1.o(.bss+0x68): multiple definition of 
> `std::numeric_limits<std::basic_string<char, std::char_traits<char>, 
> std::allocator<char> > >::is_integer'

Hmm. This isn't a specialization in <limits>, at least
numeric_limits<string> is not one I'm familiar with...

Here's what I've done to reproduce this:

cat > 1.cc
#include <limits>
#include <string>

void foo1()
{
  bool b1 = std::numeric_limits<std::string>::is_integer;
  bool b2 = std::numeric_limits<int>::is_integer;
}

cat > 2.cc
#include <limits>
#include <string>

void foo2()
{
  bool b1 = std::numeric_limits<std::string>::is_integer;
  bool b2 = std::numeric_limits<int>::is_integer;
}

cat > 3.cc
extern void foo1();
extern void foo2();

int main()
{
  foo1();
  foo2();
}

Then

%g++ 1.cc 2.cc 3.cc 
/tmp/ccVwNcTu.o(.bss+0x0): multiple definition of `std::numeric_limits<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::is_integer'
/tmp/ccrSXPkE.o(.bss+0x0): first defined here
collect2: ld returned 1 exit status

Which is a major bummer. 

%nm 1.o 2.o 

1.o:
00000000 T _Z4foo1v
00000000 B _ZNSt14numeric_limitsISsE10is_integerE
00000004 C _ZNSt17_Swap_lock_structILi0EE12_S_swap_lockE

2.o:
00000000 T _Z4foo2v
00000000 B _ZNSt14numeric_limitsISsE10is_integerE
00000004 C _ZNSt17_Swap_lock_structILi0EE12_S_swap_lockE

Seems sane. 

It looks like the best approach would be to use a base class for this
data. Here's a patch that does that: we'll have to wait for Gaby's ok
to check it in.

-benjamin


2002-03-08  Benjamin Kosnik  <bkoz@redhat.com>

	* include/std/std_limits.h: Move static const data members out of
	generic template, into base class __numeric_limits_base.

Index: include/std/std_limits.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/std/std_limits.h,v
retrieving revision 1.3
diff -c -p -r1.3 std_limits.h
*** std_limits.h	2002/01/28 22:13:10	1.3
--- std_limits.h	2002/03/08 07:15:33
*************** namespace std
*** 908,1047 ****
    //
    // The primary class traits
    //
    template<typename _Tp> 
!     struct numeric_limits 
      {
-       static const bool is_specialized = false;
- 
        static _Tp min() throw() { return static_cast<_Tp>(0); }
        static _Tp max() throw() { return static_cast<_Tp>(0); }
- 
-       static const int digits = 0;
-       static const int digits10 = 0;
-       static const bool is_signed = false;
-       static const bool is_integer = false;
-       static const bool is_exact = false;
-       static const int radix = 0;
- 
        static _Tp epsilon() throw() { return static_cast<_Tp>(0); }
        static _Tp round_error() throw() { return static_cast<_Tp>(0); }
- 
-       static const int min_exponent = 0;
-       static const int min_exponent10 = 0;
-       static const int max_exponent = 0;
-       static const int max_exponent10 = 0;
- 
-       static const bool has_infinity = false;
-       static const bool has_quiet_NaN = false;
-       static const bool has_signaling_NaN = false;
-       static const float_denorm_style has_denorm = denorm_absent;
-       static const bool has_denorm_loss = false;
- 
        static _Tp infinity() throw()  { return static_cast<_Tp>(0); }
        static _Tp quiet_NaN() throw() { return static_cast<_Tp>(0); }
        static _Tp signaling_NaN() throw() { return static_cast<_Tp>(0); }
        static _Tp denorm_min() throw() { return static_cast<_Tp>(0); }
- 
-       static const bool is_iec559 = false;
-       static const bool is_bounded = false;
-       static const bool is_modulo = false;
- 
-       static const bool traps = false;
-       static const bool tinyness_before = false;
-       static const float_round_style round_style = round_toward_zero;
      };
  
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::is_specialized;
- 
-   template<typename _Tp> 
-     const int
-     numeric_limits<_Tp>::digits;
- 
-   template<typename _Tp> 
-     const int
-     numeric_limits<_Tp>::digits10;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::is_signed;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::is_integer;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::is_exact;
- 
-   template<typename _Tp> 
-     const int
-     numeric_limits<_Tp>::radix;
- 
-   template<typename _Tp> 
-     const int
-     numeric_limits<_Tp>::min_exponent;
- 
-   template<typename _Tp> 
-     const int
-     numeric_limits<_Tp>::min_exponent10;
- 
-   template<typename _Tp> 
-     const int
-     numeric_limits<_Tp>::max_exponent;
- 
-   template<typename _Tp> 
-     const int
-     numeric_limits<_Tp>::max_exponent10;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::has_infinity;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::has_quiet_NaN;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::has_signaling_NaN;
- 
-   template<typename _Tp> 
-     const float_denorm_style
-     numeric_limits<_Tp>::has_denorm;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::has_denorm_loss;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::is_iec559;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::is_bounded;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::is_modulo;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::traps;
- 
-   template<typename _Tp> 
-     const bool
-     numeric_limits<_Tp>::tinyness_before;
- 
-   template<typename _Tp> 
-     const float_round_style
-     numeric_limits<_Tp>::round_style;
- 
    // Now there follow 15 explicit specializations.  Yes, 15.  Make sure
!   // you get the count right.
!   
    template<>
      struct numeric_limits<bool>
      {
--- 908,959 ----
    //
    // The primary class traits
    //
+   struct __numeric_limits_base
+   {
+     static const bool is_specialized = false;
+ 
+     static const int digits = 0;
+     static const int digits10 = 0;
+     static const bool is_signed = false;
+     static const bool is_integer = false;
+     static const bool is_exact = false;
+     static const int radix = 0;
+ 
+     static const int min_exponent = 0;
+     static const int min_exponent10 = 0;
+     static const int max_exponent = 0;
+     static const int max_exponent10 = 0;
+     
+     static const bool has_infinity = false;
+     static const bool has_quiet_NaN = false;
+     static const bool has_signaling_NaN = false;
+     static const float_denorm_style has_denorm = denorm_absent;
+     static const bool has_denorm_loss = false;
+ 
+     static const bool is_iec559 = false;
+     static const bool is_bounded = false;
+     static const bool is_modulo = false;
+ 
+     static const bool traps = false;
+     static const bool tinyness_before = false;
+     static const float_round_style round_style = round_toward_zero;
+   };
+ 
    template<typename _Tp> 
!     struct numeric_limits : public __numeric_limits_base 
      {
        static _Tp min() throw() { return static_cast<_Tp>(0); }
        static _Tp max() throw() { return static_cast<_Tp>(0); }
        static _Tp epsilon() throw() { return static_cast<_Tp>(0); }
        static _Tp round_error() throw() { return static_cast<_Tp>(0); }
        static _Tp infinity() throw()  { return static_cast<_Tp>(0); }
        static _Tp quiet_NaN() throw() { return static_cast<_Tp>(0); }
        static _Tp signaling_NaN() throw() { return static_cast<_Tp>(0); }
        static _Tp denorm_min() throw() { return static_cast<_Tp>(0); }
      };
  
    // Now there follow 15 explicit specializations.  Yes, 15.  Make sure
!   // you get the count right.  
    template<>
      struct numeric_limits<bool>
      {



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]