Search code examples
c++poco-librarieswstring

Poco::Path compiles with const wchar_t* but behaves unexpectedly


Working with Poco::Path I've found a very curious error. See following code:

#include <iostream>
#include <string>
#include <Poco/Path.h>

int main()
{
  std::wstring a_path = L"c:\\temp";

  //Poco::Path from_wstring(a_path); // ERROR: fails to compile, expected
  Poco::Path from_wchar_t(a_path.c_str()); // compiles... unexpected

  std::cout << from_wchar_t.toString() << std::endl;

  return 0;
}

But the output of the above program is (in Windows):

\

instead of the expected:

c:\temp

Reviewing the Poco::Path documentation I see no constructor expecting std::wstring (that's why the first path fails) nor const wchar_t*, only from std::string and const char* (both UTF-8).

How is it compiling with const wchar_t* and why the unexpected output (wrong path)?


Solution

  • When creating the mvce for this question I figured out the problem. I've decided to document it here in case it is helpful for somebody else.

    The code snippet shown in the question is part of a huge project so I was missing a compilation warning:

    warning C4800: 'const wchar_t *' : forcing value to bool 'true' or 'false' (performance warning)

    Then I realized that there is a constructor Poco::Path::Path(bool absolute) and that the compiler was making the cast from pointer to bool automatically, producing then the unexpected behavior. The \ of the output corresponds to an empty absolute path, its initial value when using such constructor.


    For those interested in a workaround, I'm now using a UTF-16 to UTF-8 conversion:

    #include <boost/locale/encoding.hpp>
    // ...
    std::wstring a_path = L"c:\\temp";
    Poco::Path utf8_path(boost::locale::conv::utf_to_utf<char>(a_path));