Skip to content
Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

std::source_location is Broken

elbeno, 16 November, 202316 November, 2023

Everyone knows that the best way to get something done on the Internet is with an inflammatory title and a potentially incorrect contention, so here goes.

What do you if you want to capture/log the filename of an assertion? Prior to C++20, you use good old __FILE__, which gives you a C-style array of chars. But of course this is a macro, and means that your logging/assertion code has to be a macro. With all the usual downsides of macros. Ho hum, that’s how it is for now, and it works. You go on your way.

After upgrading to C++20, you wonder if you can upgrade your logging/assertion code to use std::source_location. Then maybe you could get rid of the macros. It looks odd at first, because you have to set it up as a default argument to your log function. But hey, this was someone’s clever solution to the problem, right? Obviously arguments are supplied at the call site, and default arguments are arguments, so they are too. So the std::source_location default argument picks up the location of the call site, and you can grab the file_name from it as a const char*.

But… now it doesn’t work. Because that’s not how your logging works. You’re working in embedded. No room for strings in your binary. Instead, you model your (statically-known) strings as types like string_constant<'H', 'e', 'l', 'l', 'o'>, you use nm to extract the symbols from your library, and you generate tiny function specializations which turn the types into numbers, and melt away with LTO. (Like this.)

You need strings to be types. You need to know the size at compile time. std::source_location::file_name() gives you a const char* – you don’t know the size of the string. And because it has to be a function argument, it can’t be constexpr. There is no way to get back into type land. (At least, none that I know of yet, and believe me, I’ve tried. If you know how, let me know!) It’s the same story for the intrinsics that std::source_location is built upon (__builtin_FILE_NAME).

So you sadly accept that until and unless you get jam tomorrow another mechanism to do this, be it constexpr function arguments or whatever, you’re stuck with __FILE__, which works, because it gives you a sized char array which you can turn into a type.

Of course the irony here is that std::source_location provides information that is known only at compile time. But we can’t use that information fully at compile time, because it’s inadequately specified/implemented.

C++

Post navigation

Previous post
Next post

Related Posts

Development of an Algorithm

21 June, 201722 June, 2017

Here’s an exercise: given a nice piece of code sitting in a file, how do you take that code and make it generic, in the style of an STL algorithm? For our example, let’s consider an algorithm that isn’t (yet) in the STL. First, the problem it solves. Imagine that…

Read More

CHRONO + RANDOM = ?

24 October, 201624 October, 2016

Being a quick sketch combining <chrono> and <random> functionality, with cryptarithmetic interludes… At CppCon this year there were several good talks about randomness and time calculations in C++. On randomness: Walter Brown’s What C++ Programmers Need to Know About Header <random> and Cheinan Marks’ I Just Wanted a Random Integer!…

Read More

How to print anything in C++ (part 1)

1 February, 201530 June, 2015

Part 1 Part 2 Part 3 Part 4 Part 5 Postscript I thought I’d have a go at writing some code that could print things. A pretty-printer, if you like. What I want to be able to do is this: // Print x correctly, where x is ANY type. cout

Read More
©2026 Why is a raven like a writing desk? | WordPress Theme by SuperbThemes