Bug 79694 - libstdc++ headers: explicit specialization of function must precede its first use
libstdc++ headers: explicit specialization of function must precede its first...
Status: CLOSED UPSTREAM
Product: Red Hat Linux
Classification: Retired
Component: gcc3 (Show other bugs)
8.0
All Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2002-12-15 08:21 EST by Sysoltsev Slawa
Modified: 2007-04-18 12:49 EDT (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-10-01 10:57:26 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Patch with changes to <fstream> to made it more correct according C++ standard (1.13 KB, patch)
2002-12-15 09:03 EST, Sysoltsev Slawa
no flags Details | Diff

  None (edit)
Description Sysoltsev Slawa 2002-12-15 08:21:04 EST
Description of problem:
In file /usr/include/c++/3.2/fstream:292 there is declaration:
  template<>
    basic_filebuf<char>::int_type
    basic_filebuf<char>::_M_underflow_common(bool __bump);

which is explicit specialization of std::basic_filebuf<_CharT, 
_Traits>::_M_underflow_common member function.

But this function is used previously in this file in ‘virtual int_type underflow
()’ function in its body (line 140):
      virtual int_type
      underflow() { return _M_underflow_common(false); }


This is violation of ISO C++ standards, paragraph 14.7.3, clause 6:

“ If a template, a member template or the member of a class template is 
explicitly specialized then that specialization shall be declared before the 
first use of that specialization that would cause an implicit instantiation
to take place, in every translation unit in which such a use occurs; no 
diagnostic is required. If the program does not provide a definition for an 
explicit specialization and either the specialization is used in a way that 
would cause an implicit instantiation to take place or the member is a virtual 
member function, the program is illformed, no diagnostic required. “

It is ambiguous what method will be called from ‘underflow’ function – 
implicitly instantiated common _M_underflow_common or consequent 
specialization – that’s why such code should be restricted by C++ compiler.

GNU C++ compiler accepts this code violating C++ standards, but bigger problem 
here is that erroneous code is in system headers. Custom compiler couldn't 
compile this.

Error here has to be worked around to increase Red Hat linux portability: in 
header /usr/include/c++/3.2/fstream you should provide bodies for ‘underflow’ 
and ‘uflow’ functions after _M_underflow_common specialization (after line 299) 
or not to provide them at all.


Version-Release number of selected component (if applicable):


How reproducible:
Every time

Steps to Reproduce:
1. GNU C++ compiler allow described construction, you won't be able to 
reproduce it with standart compiler.
    
Actual results:
compilation error compiling test case which uses <fstream>:
/usr/include/c++/3.2/fstream(292): error: explicit specialization of 
function "std::basic_filebuf<_CharT, _Traits>::_M_underflow_c
ommon [with _CharT=char, _Traits=std::char_traits<char>]" must precede its 
first use
      basic_filebuf<char>::_M_underflow_common(bool __bump);


Expected results:
Succesfull compilation with using <fstream> header.

Additional info:
I'll try to attach patch for <fstream> with changes I was speaking about.
Comment 1 Sysoltsev Slawa 2002-12-15 09:03:32 EST
Created attachment 88743 [details]
Patch with changes to <fstream> to made it more correct according C++ standard
Comment 2 Benjamin Kosnik 2003-01-10 20:21:43 EST
This patch applies to gcc-3_3-branch and gcc-3_2-branch, but not mainline.

2003-01-10  Benjamin Kosnik  <bkoz@redhat.com>
	    Sysoltsev Slawa  <Vyatcheslav.Sysoltsev@intel.com>

	PR libstdc++/
	* include/std/std_fstream.h (basic_filebuf::uflow): Declare.
	(basic_filebuf::underflow): Declare.
	Move definitions.


Index: include/std/std_fstream.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/std/std_fstream.h,v
retrieving revision 1.15
diff -c -p -r1.15 std_fstream.h
*** include/std/std_fstream.h	27 Dec 2002 23:03:03 -0000	1.15
--- include/std/std_fstream.h	11 Jan 2003 00:51:37 -0000
*************** namespace std
*** 234,244 ****
  
        // [documentation is inherited]
        virtual int_type
!       underflow() { return _M_underflow_common(false); }
  
        // [documentation is inherited]
        virtual int_type
!       uflow() { return _M_underflow_common(true); }
  
        // [documentation is inherited]
        virtual int_type
--- 234,244 ----
  
        // [documentation is inherited]
        virtual int_type
!       underflow();
  
        // [documentation is inherited]
        virtual int_type
!       uflow();
  
        // [documentation is inherited]
        virtual int_type
*************** namespace std
*** 431,437 ****
        }
      };
  
!   // Explicit specializations, defined in src/fstream.cc.
    template<> 
      basic_filebuf<char>::int_type 
      basic_filebuf<char>::_M_underflow_common(bool __bump);
--- 431,437 ----
        }
      };
  
!   // Explicit specialization declarations, defined in src/fstream.cc.
    template<> 
      basic_filebuf<char>::int_type 
      basic_filebuf<char>::_M_underflow_common(bool __bump);
*************** namespace std
*** 441,446 ****
--- 441,458 ----
      basic_filebuf<wchar_t>::int_type 
      basic_filebuf<wchar_t>::_M_underflow_common(bool __bump);
   #endif
+ 
+   // Generic definitions.
+   template <typename _CharT, typename _Traits>
+     basic_filebuf<_CharT, _Traits>::int_type
+     basic_filebuf<_CharT, _Traits>::underflow() 
+     { return _M_underflow_common(false); }
+ 
+   template <typename _CharT, typename _Traits>
+     basic_filebuf<_CharT, _Traits>::int_type
+     basic_filebuf<_CharT, _Traits>::uflow() 
+     { return _M_underflow_common(true); }
+ 
  
    // [27.8.1.5] Template class basic_ifstream
    /**
Comment 3 Benjamin Kosnik 2004-10-01 10:57:26 EDT
Fixed in gcc-3.4.x. Intel compilers are much more strict about this.

I believe this was fixed in 3.3.x as well. 

Closing, reopen if believe I am in error.

-benjamin

Note You need to log in before you can comment on or make changes to this bug.