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 thats 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.
Created attachment 88743 [details] Patch with changes to <fstream> to made it more correct according C++ standard
This patch applies to gcc-3_3-branch and gcc-3_2-branch, but not mainline. 2003-01-10 Benjamin Kosnik <bkoz> Sysoltsev Slawa <Vyatcheslav.Sysoltsev> 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 /**
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