Home > Software design >  How to force the C compiler to warn when a specific std class function is called?
How to force the C compiler to warn when a specific std class function is called?

Time:01-19

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
}

Live demo

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.

  •  Tags:  
  • Related