[2.90.9] planning for the next release

scott snyder snyder@d0sgibnl1.fnal.gov
Sat Apr 1 00:00:00 GMT 2000


> Yeah. This is actually going to be necessary, unfortunately. Thanks for 
> this -- anything else? I'm not quite sure I have the test file I was 
> using for your other bug anymore... perhaps you can just sync up with me 
> and let me know what is outstanding? I thought you had two outstanding 
> bugs. This was one of them. I'd like to get both resolved before I get to 
> far into the libio merge. . . 

I think that was the only I/O bug that i had reported that was still
outstanding -- at least that's the only one for which i still had a local
patch.  Perhaps you were thinking of that problem of the string
extractors not setting failbit at EOF?  I eventually did get a defect
report submitted for that, but a fix for it did get into cvs.


Anyway, here are the remaining libstdc++ patches i have in my local tree.
There's less commentary than i'd like, but it's getting late...

sss


=====================================================

1. There was some code in our system which was relying on being able
   to output a double to a stream using operator<<, then read it 
   back in again with operator>> and get exactly the same value.
   To do this, it was cranking the precision setting way up (i think
   it set it to 30 or thereabouts).  However, this was defeated
   by the test in locale_facets which limited the precion to
   numeric_limits<>::digits10 --- i think the value of digits10 may have
   had the fractional part truncated, so it doesn't give quite enough
   precision.  I just allowed another few digits in the output -- shouldn't
   do any harm.


2000-02-06  scott snyder  <snyder@fnal.gov>

	* bits/locale_facets.tcc (do_put): Allow a couple extra digits of
	precision beyond that which we get from numeric_limits::digits10.

Index: bits/locale_facets.tcc
===================================================================
RCS file: /cvs/libstdc++/libstdc++/bits/locale_facets.tcc,v
retrieving revision 1.32
diff -u -p -r1.32 locale_facets.tcc
--- locale_facets.tcc	2000/03/21 06:24:04	1.32
+++ locale_facets.tcc	2000/03/29 06:19:05
@@ -1194,7 +1194,7 @@ namespace std
     num_put<_CharT, _OutIter>::
     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
     {
-      const streamsize __max_prec = numeric_limits<double>::digits10;
+      const streamsize __max_prec = numeric_limits<double>::digits10 + 3;
       streamsize __prec = __io.precision();
       // Protect against sprintf() buffer overflows.
       if (__prec > __max_prec) 


=====================================================

2. The current cvs version of g++ miscompiles the max() and min()
   template functions in libstdc++.

Here's an example, tested on an i686-linux platform.

-----------------------------------------
extern "C" int printf (...);

template <class T>
const T& max (const T& a, const T& b)
{
  return (a > b) ? a : b;
}


int main ()
{
  const int& x = max (1, 2);
  const int& y = max (3, 4);
  printf ("%d\n", x);
}
-----------------------------------------

I get the output

$ g++ -o x x.cc
$ ./x
4


If one looks at the generated code, it seems that what's happening
in max() is that the inputs get copied to stack temporaries,
and the reference returned is actually a reference to one of these
temporaries --- which, of course, becomes invalid after max() returns.

This seems to occur due to the following in cp/call.c:build_conditional_expr:

  /* Convert from reference types to ordinary types; no expressions
     really have reference type in C++.  */
  arg2 = convert_from_reference (arg2);
  arg3 = convert_from_reference (arg3);

At one point, i had managed to convince myself that the definition of
max() as above was actually incorrect according to the standard,
but just now, i can't seem to find the justification for that statement.

The definitions of max() and min() in libstdc++ are of the same form
as max() above, so they get bitten by this behavior.  This can be
avoided by rewriting them to avoid using a conditional expression:

2000-02-25  scott snyder  <snyder@fnal.gov>

	* stl/bits/stl_algobase.h (max, min): Don't use comparison
	operator.


Index: stl/bits/stl_algobase.h
===================================================================
RCS file: /cvs/libstdc++/libstdc++/stl/bits/stl_algobase.h,v
retrieving revision 1.13
diff -u -p -r1.13 stl_algobase.h
--- stl_algobase.h	2000/02/04 23:52:47	1.13
+++ stl_algobase.h	2000/03/29 06:42:45
@@ -85,24 +85,28 @@ inline void swap(_Tp& __a, _Tp& __b) {
 
 template <class _Tp>
 inline const _Tp& min(const _Tp& __a, const _Tp& __b) {
-  return __b < __a ? __b : __a;
+  //return __b < __a ? __b : __a;
+  if (__b < __a) return __b; return __a;
 }
 
 template <class _Tp>
 inline const _Tp& max(const _Tp& __a, const _Tp& __b) {
-  return  __a < __b ? __b : __a;
+  //return  __a < __b ? __b : __a;
+  if (__a < __b) return __b; return __a;
 }
 
 #endif /* __BORLANDC__ */
 
 template <class _Tp, class _Compare>
 inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) {
-  return __comp(__b, __a) ? __b : __a;
+  //return __comp(__b, __a) ? __b : __a;
+  if (__comp(__b, __a)) return __b; return __a;
 }
 
 template <class _Tp, class _Compare>
 inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) {
-  return __comp(__a, __b) ? __b : __a;
+  //return __comp(__a, __b) ? __b : __a;
+  if (__comp(__a, __b)) return __b; return __a;
 }
 
 //--------------------------------------------------


=====================================================

3. The test ios_manip_fmtflags.cc also didn't run correctly with
   the cvs version of g++.  The code was passing a temporary
   to imbue(); the data structures owned by this temporary locale
   were getting deleted when the temporary locale was deleted,
   resulting in references to freed memory when the locale
   was later used.  I redid this to avoid the temporary:


2000-03-06  scott snyder  <snyder@fnal.gov>

	* testsuite/27_io/ios_manip_fmtflags.cc (test01): Don't give a
	temporary to imbue().


Index: testsuite/27_io/ios_manip_fmtflags.cc
===================================================================
RCS file: /cvs/libstdc++/libstdc++/testsuite/27_io/ios_manip_fmtflags.cc,v
retrieving revision 1.1
diff -u -p -r1.1 ios_manip_fmtflags.cc
--- ios_manip_fmtflags.cc	1999/09/21 02:20:37	1.1
+++ ios_manip_fmtflags.cc	2000/03/29 06:44:27
@@ -57,7 +57,8 @@ void test01()
   std::cout << ":" << std::setw(3) << std::left << true << ":" << std::endl;
   std::cout << ":" << std::setw(3) << std::right << false << ":" << std::endl;
 
-  std::cout.imbue(std::locale(std::locale(), new MyNP));
+  std::locale loc = std::locale (std::locale(), new MyNP);
+  std::cout.imbue(loc);
 
   std::cout << std::boolalpha;
   std::cout << true << " " << false << std::endl;


=====================================================

4. bitset_shift.cc was also giving compilation errors.
   I haven't tested this recently to see if this is still a problem, though.

Index: testsuite/23_containers/bitset_shift.cc
===================================================================
RCS file: /cvs/libstdc++/libstdc++/testsuite/23_containers/bitset_shift.cc,v
retrieving revision 1.1
diff -u -p -r1.1 bitset_shift.cc
--- bitset_shift.cc	2000/01/31 21:20:22	1.1
+++ bitset_shift.cc	2000/03/29 06:52:12
@@ -68,19 +68,22 @@ template <size_t size>
   
     initialise(size);
 
-    std::bitset<size> original = std::string(original_bits); 
+    //std::bitset<size> original = std::string(original_bits); 
+    std::bitset<size> original = std::bitset<size> (std::string(original_bits)); 
 
     for (size_t shift_step=0; shift_step==0 || shift_step<size; shift_step++) {
       shift_arrays(shift_step, size);
 
       shifted = original;
       shifted <<= shift_step;
-      correct = std::string(left_shifted);
+      //correct = std::string(left_shifted);
+      correct = std::bitset<size> (std::string(left_shifted));
       test &= shifted == correct;
 
       shifted = original;
       shifted >>= shift_step;
-      correct = std::string(right_shifted);
+      //correct = std::string(right_shifted);
+      correct = std::bitset<size> (std::string(right_shifted));
       test &= shifted == correct;
     }
 

=====================================================
5. Two more remarks:

   - The cvs version of g++ has a bug that will cause it to build
     a bad shared library on linux if it is generating code for i686.
     Using -mpentium or lower avoids this bug.  I reported this
     a little while ago, and i think it is understood how to fix
     it, but it hasn't been implemented yet.  In the meantime,
     i've patched src/Makefile.in to force -mpentium for my compiles.

   - I also patch mkcheck.in to turn off optimization when compiling
     the tests, since g++ is too unstable at the moment for that.


hope this helps,
sss


More information about the Libstdc++ mailing list