I'm trying to use UTF-8 std::string and std::filesystem::path in a fool-proof way on Windows 10 where Beta: Use Unicode UTF-8 for worldwide language support is likely off. C 17 or above.
To go from a path to a UTF-8 string, I have to use path.u8string() instead of path.string().
And to go from a UTF-8 string to a path, I have to use u8path() instead of path().
How can I make the compiler help catch me when I call the "wrong" functions? This includes implicit construction of path, that is:
#include <filesystem>
#include <string>
void foo(const std::filesystem::path& path) {}
std::string pathString; // UTF-8 string.
foo(pathString) // Wrong. path() expects native encoding.
foo(u8path(pathString)) // Make sure to always use u8path().
std::filesystem::path path;
path.string() // Wrong. Returns native encoding.
path.u8string() // Make sure to always use u8string().
Can I force the C compiler to warn me when specific functions are called? On either MSVC, GCC or Clang, preferably on all? Can I easily prevent myself from making these errors in some other way?
CodePudding user response:
GCC and clang have a poison pragma which you might find helpful here. Unfortunately, you can only poison tokens, and not fully qualified names, so while you can do:
#pragma GCC poison string
you cannot do (for example):
#pragma GCC poison std::filesystem::path::string
Still, maybe this is something you could wrap in a #ifdef and enable it periodically in a test build to weed out errors in your code.
Here's a fully worked example:
#include <filesystem>
#include <string>
#pragma GCC poison string
int main ()
{
std::filesystem::path path;
auto x = path.string(); // error: attempt to use poisoned "string"
auto y = path.u8string(); // OK
}
Also, see this question for an MSVC solution. More #ifdef's coming to a screen near you :)
CodePudding user response:
A hacky approach I've used in similar situations in the past: Edit the system header(s) and add [[deprecated]] to the functions that you don't want to use.
