GCC 7.3.0 -std=gnu++17 failed to getline() from std::ifstream

Christian Franke Christian.Franke@t-online.de
Tue Jun 12 18:02:00 GMT 2018


Ivan Shynkarenka wrote:
> I use x64 bit Cygwin and it failed in my home, work and Appveyor.  I add
> cygcheck.out with my environment.
>
> I'm sorry about misspell prefix space in my prev example. Please try the
> following one:
>
> #include <fstream>
> #include <iostream>
>
> int main(int argc, char** argv)
> {
>      std::string line;
>      std::ifstream stream("test.cpp");
>      while (getline(stream, line))
>          std::cout << line << std::endl;
>      return 0;
> }
>
> g++ -std=gnu++17 test.cpp

Could reproduce this with 32 and 64 bit Cygwin g++ 7.3.0

A comparison of preprocessor (-E) outputs shows that the "extern 
template" declarations for getline() are only visible for C++ <= 14. 
These are guarded by "__cplusplus <= 1402" in basic_string.tcc. This 
should tell the compiler to generate new code for getline() if C++17 is 
enabled instead of calling the (now incompatible) function in 
cygstdc++-6.dll.

A comparison of assembly (-S) outputs shows that this does not work: If 
C++17 is enabled, the compiler correctly generates local code for 
getline(istream &, string &) but this code calls an external 
getline(istream &, string &, char). Then the linker generates a call to 
this getline() in cygstdc++-6.dll.

This is because there is a bogus prototype specialization for 
getline(istream &, string &, char) in basic_string.h but no 
corresponding implementation in basic_string.tcc. This has apparently an 
equivalent effect as 'extern template'.

The attached patch for
   /usr/lib/gcc/*-pc-cygwin/7.3.0/include/c++/bits/basic_string.h
fixes this.

Christian

-------------- next part --------------
--- basic_string.h.orig	2018-05-03 06:22:46.000000000 +0200
+++ basic_string.h	2018-06-12 15:56:03.215179300 +0200
@@ -6329,18 +6329,6 @@
     { return std::getline(__is, __str); }
 #endif
 
-  template<>
-    basic_istream<char>&
-    getline(basic_istream<char>& __in, basic_string<char>& __str,
-	    char __delim);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  template<>
-    basic_istream<wchar_t>&
-    getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
-	    wchar_t __delim);
-#endif  
-
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
-------------- next part --------------

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


More information about the Cygwin mailing list