Sometime ago in a code-review (C++) I suggested to change the input argument from Path type to Optional<Path>, where the function has specific logic for unset path. It looks for me intuitively better, but the author appealed that Path::empty() (empty path) method should semantically mean the same as unset Optional.

My sole rational argument is that empty path may also be interpreted as the current working directory. But then I also thought that . may be used as CWD as well.

What is a good default semantic for a cross-platform API path emptiness? E.g. . may be not so common outside *nix OSes, or there are already some common semantics in any popular programming language.

  • en.cppreference.com/w/cpp/filesystem/path Note that . must represent the current directory. Systems which handle it differently must still support . as the current directory. – Justin Jan 14 '19 at 17:11
  • @Justin good point! – abyss.7 Jan 14 '19 at 17:17
  • 2
    I would say that optional<path> is very different from path, just like how optional<string> is very different from string. It may be that the empty path is what you want, or it may be that it doesn't work for the case and you need an optional. It depends – Justin Jan 14 '19 at 17:20
  • There's another option: having a second function doFooWithoutPath(), which delegates the responsibility to the caller to call the correct method. I'm personally not fond of methods accepting optional parameters (you know at the call site that you don't have a value), and I don't believe Path::empty() convey enough information in this case (why would an empty path means that it is unset?). – Vincent Savard Jan 15 '19 at 15:54
  • @VincentSavard: "you know at the call site that you don't have a value" Do you? What if you have a function that searches for a file and returns an optional<path> which is nullopt if no file was found? Unless you check that value, you don't know if the path exists. And maybe your local code doesn't care; why should you not pass that optional to others? – Nicol Bolas Jan 15 '19 at 17:44

A function which takes an optional<path> makes it abundantly, unquestionably clear that it's OK for the user to not provide a path. A function which takes a path may or may not have it be OK for a real path to be provided. You have to look it up in the docs to know for sure.

However, if you have an API where many functions take optional<path> and many functions that take path, then the user can probably infer that any function that takes path directly is a function that won't work if that path is empty. So consistent use of optional for such types has a purpose.


From the draft standard [fs.path.generic/3]:

The dot filename is treated as a reference to the current directory.

So you always have an unambiguous "current directory" path. I would be surprised by a system that used an empty path to mean the same as ..


What is a good default semantic for a cross-platform API path emptiness?

std::optional<path> is a good way to represent "path argument is optional". Another good way is signature polymorphism (provide two entry points):

void your_api(int other_args, std::filesystem::path& the_path);

void your_api(int other_args);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.