c++c++17cygwinheader-filesc++pmr

cygwin g++ can't find pmr namespace and related issues


Ok so I decided to compile some code from godbolt locally on my Windows 10 64bit using Cygwin and the cygwin terminal. It compiles fine on godbolt, but cygwin/mingw64 g++ spits out loads of errors along the lines of:

jsontest.cpp:310:23: error: ‘string’ is not a member of ‘std::pmr’; did you mean ‘std::string’?
  310 | auto expand(std::pmr::string s, ospolicy policy) {
      |                       ^~~~~~
In file included from /usr/lib/gcc/x86_64-pc-cygwin/11/include/c++/string:39,
                 from jsontest.cpp:2:
/usr/lib/gcc/x86_64-pc-cygwin/11/include/c++/bits/stringfwd.h:79:33: note: ‘std::string’ declared here
   79 |   typedef basic_string<char>    string;
                  ^~~~~~

There are a lot more issues but I think they are all related to this one. When I looked into the headerfile for #include<string> (which I did), std::pmr::string is defenitely defined there. The file stringfwd.h just forward declares basic_string templates so it should still find the definitions.

This is the section inside the string headerfile:

#if __cplusplus >= 201703L && _GLIBCXX_USE_CXX11_ABI
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  namespace pmr {
    template<typename _Tp> class polymorphic_allocator;
    template<typename _CharT, typename _Traits = char_traits<_CharT>>
      using basic_string = std::basic_string<_CharT, _Traits,
                         polymorphic_allocator<_CharT>>;
    using string    = basic_string<char>;
#ifdef _GLIBCXX_USE_CHAR8_T
    using u8string  = basic_string<char8_t>;
#endif
    using u16string = basic_string<char16_t>;
    using u32string = basic_string<char32_t>;
#ifdef _GLIBCXX_USE_WCHAR_T
    using wstring   = basic_string<wchar_t>;
#endif
  } // namespace pmr
//...
} // namespace std

You can see that the std::pmr::string typedef is guarded and only availabe when the C++ version is greater than 17 (as polymorphic memory resources are only available from C++17) and something about the CXX ABI.

I'm using gcc 11.3 which should be able to support even C++20 language features. I'm not getting it... what am I doing differently than godbolt?

EDIT:

Try this to reproduce:

  1. Download cygwin from here and install it the usual way (add g++ to environment vars)
  2. Create testfolder with the following file:

test_pmr.cpp (CompilerExplorer)

#include <iostream>
#include <memory_resource>

int main()
{
    std::pmr::string str = "Hello World!";

    std::cout << str << std::endl;
}
  1. Compile using the following command:

    g++ -std=c++20 test_pmr.cpp -s -o test_pmr

When I follow this I get this error:

test_pmr.cpp: In function ‘int main()’:
test_pmr.cpp:6:15: error: ‘string’ is not a member of ‘std::pmr’; did you mean ‘std::string’?
    6 |     std::pmr::string str = "Hello World!";
      |               ^~~~~~
In file included from /usr/lib/gcc/x86_64-pc-cygwin/11/include/c++/iosfwd:39,
                 from /usr/lib/gcc/x86_64-pc-cygwin/11/include/c++/ios:38,
                 from /usr/lib/gcc/x86_64-pc-cygwin/11/include/c++/ostream:38,
                 from /usr/lib/gcc/x86_64-pc-cygwin/11/include/c++/iostream:39,
                 from test_pmr.cpp:1:
/usr/lib/gcc/x86_64-pc-cygwin/11/include/c++/bits/stringfwd.h:79:33: note: ‘std::string’ declared here
   79 |   typedef basic_string<char>    string;
      |                                 ^~~~~~
test_pmr.cpp:8:18: error: ‘str’ was not declared in this scope; did you mean ‘std’?
    8 |     std::cout << str << std::endl;
      |                  ^~~
      |                  std

EDIT2:

It works using only MSYS with static linking:

g++ -std=c++20 -static-libgcc -static-libstdc++ test_pmr.cpp -s -o test_pmr

So the problem seems to lie in an incorrect stdlib configuration that ships with cygwin.


Solution

  • To use anything in the std::pmr namespace, it looks like you need to add -D_GLIBCXX_USE_CXX11_ABI to your general compiler flags. I got a clean and successful compile and execute with g++ -std=c++20 -Wall -Wextra -Werror -D_GLIBCXX_USE_CXX11_ABI test_pmr.cpp -s -o test_pmr.exe