I have a constexpr
function and I'm trying to strip the file name from the __FILE__
macro, that is, remove everything but the path. I sketched up this basic function to do so, and I made it constexpr
in hopes that the compiler can deduce the result and just place that calculated result as a string in the final binary. The function isn't perfect, just a simple mock-up.
constexpr const char* const get_filename()
{
auto file{ __FILE__ };
auto count{ sizeof(__FILE__) - 2 };
while (file[count - 1] != '\\')
--count;
return &file[count];
}
int main()
{
std::cout << get_filename() << std::endl;
return 0;
}
The problem is that this is not being evaluated at compile time (build: MSVC x64 Release Maximum Speed optimization). I'm assuming this is because of returning a pointer to something inside a constant string in the binary, which is essentially what the function is doing. However, what I want the compiler to do is parse the get_filename
function and somehow return the string literal "main.cpp"
, for example, instead of returning a pointer of that substring. Essentially, I want this to compile down so that the final binary just has main.cpp
in it, and nothing else part of the __FILE__
macro. Is this possible?
Because you don't want the full __FILE__
path in the final binary, we must copy the string to a std::array
:
constexpr auto get_filename()
{
constexpr std::string_view filePath = __FILE__;
constexpr auto count = filePath.rfind("\\");
static_assert(count != std::string::npos);
std::array<char, count> fileName{};
std::copy(filePath.data() + count + 1, filePath.data() + filePath.size(), fileName.data());
return fileName;
}
And specify constexpr
when calling the get_filename
function:
constexpr auto fileName = get_filename();
std::cout << fileName.data();
Alternatively, since C++20, you could use consteval
to force it to be evaluated at compile time:
consteval auto get_filename();
Here's the test on godbolt, it uses printf
instead of std::cout
for a shorter asm.