3

The C++ macro __FILE__ typically includes the full path (with many compilers).

For my tracing, I want just the file name, not the full path.

Is there a built-in macro for this in any version of C++ or do I have to write my own?

This is not quite a duplicate of __FILE__ macro shows full path. That question is targeted at the 'C' language, and answers to that question which are C++ are actually incorrect for that question. This question is targeted specifically at C++.

6
  • Is there any particular reason this should be a macro? The C++ language itself is very capable at solving this problem. Commented Jun 3 at 0:55
  • 4
    Note there also is std::source_location. If you can, avoid using macros Commented Jun 3 at 3:23
  • std::source_location still gives the full path, so it doesn't actually solve the problem. Yes, you could create a function that does the same thing, but a macro doesn't require () and is also easier to read for new team members who aren't used to C++. They see __LINE__ and __FUNCTION__ which they're used to and then [new macro] which looks the same. For the curious, they may not think that macro existed, but they can then find out that it's implemented in the code. Commented Jun 3 at 15:17
  • Indeed, C++ offers different possibilities than C (for example en.cppreference.com/w/cpp/utility/source_location/… ) and the currently identified duplicate seems not suitable. I vote to reopen this question. Commented Jun 3 at 18:10
  • For me, c++ foo.cpp the __FILE__ is foo.cpp. But c++ /home/eljay/proj/foo.cpp the __FILE__ is /home/eljay/proj/foo.cpp. Commented Jun 4 at 13:46

1 Answer 1

2

In C++20 or higher, the following macro implements the desired behavior.

It's a small snippit of code and works the same way that __FILE__ does.

#define FILENAME ([]{ \
  constexpr auto ret {std::string_view(__FILE__).substr(std::string_view(__FILE__).find_last_of("/\\") + 1).data()};         \
  return ret;           \
}())
Sign up to request clarification or add additional context in comments.

4 Comments

The name __FILENAME__ contains two consecutive underscores, so it is reserved for use by the implementation. Don’t use it in your code.
@DrewDormann No it should not throw anything. If there is a slash then find_last_of() will return its index, and strstr(index+1) will return everything following the slash, as expected. But, if there is no slash then find_last_of() will return string_view::npos, which is an unsigned type of maximum value, so npos + 1 will simply wrap back to 0, which is well-defined behavior, and substr(0) will just return the original string as-is. So, there is no out of bounds access in either case, and the result will be the correct file name whether a slash is present or not.
Identifiers beginning with underscore followed by a capital letter (as in _FILENAME_) are reserved for the implementation, as are many others. See en.cppreference.com/w/cpp/preprocessor/replace.html , en.cppreference.com/w/cpp/language/identifiers.html & stackoverflow.com/questions/228783/…
Fixed Jesphers remark. Also updated the macro to ensure that it forces compile-time evaluation regardless of optimization settings for the compiler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.