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:
test_pmr.cpp (CompilerExplorer)
#include <iostream>
#include <memory_resource>
int main()
{
std::pmr::string str = "Hello World!";
std::cout << str << std::endl;
}
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.
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