taocpp / PEGTL

Parsing Expression Grammar Template Library
Boost Software License 1.0
1.94k stars 228 forks source link

Compile error in file_reader.hpp on Windows, std::filesystem::path uses wchar_t* which cannot be passed to std::fopen expecting char* #211

Closed dennisferron closed 4 years ago

dennisferron commented 4 years ago

On Windows 10, compiling with gcc on mingw / msys2, std::filesystem::path::c_str() returns a const wchar_t while std::fopen takes a const char_t. This causes a compile error.

C:/Users/dferr/CLionProjects/PEGTL/include/tao/pegtl/internal/file_reader.hpp:29:46: error: cannot convert 'const value_type*' {aka 'const wchar_t*'} to 'const char*'
       if( auto* file = std::fopen( path.c_str(), "rb" ) )

You won't be able to fix it with a simple cast. It will require a UTF-16LE aware string conversion.

dennisferron commented 4 years ago

I'd like to fix this and send a pull request, but it looks like the only portable way to do the encoding conversion, std::codecvt_utf8_utf16, was introduced with C++11 and deprecated (without a replacement!) in C++17.

Zooming out to the larger scope, I see an alternative would be to use a wide char version of the file open function, and that's exactly what you've already did if _MSC_VER is defined (the compile error occurred in the preprocessing branch for MINGW32 and not _MSC_VER. If I change the preprocessor guards so that I use the _MSC_VER of TAO_PEGTL_NAMESPACE::internal::file_open's implementation using ::_wfopen_s it does compile.

However then I get a linker error: undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'

wravery commented 4 years ago

Lots of platforms still require linking against a separate filesystem library (-lfilesystem), try adding that?

ColinH commented 4 years ago

@dennisferron Does -lfilesystem fix the linker error with your patched code?

Amphaal commented 4 years ago

https://stackoverflow.com/questions/11352641/boostfilesystempath-and-fopen

ColinH commented 4 years ago

Thanks for the pull request, hopefully this will work for everybody :-)