Hi everyone.

I've been thinking about this for a while now, and from some conversations I've had about it, I believe there could be some interest - but that, of course, won't happen without a proposal. So here goes. What I hope to be my first proposal.

The idea is straightforward. Through static_assert, we can already opt to provide fixed (string literal) messages to the build log upon assertion failure. We cannot, however, opt to provide contextual information, such as the values of constant expressions that lead to the failure, without compiler-specific tricks. This can make debugging failed static assertions more complicated than I believe it could otherwise be.

My proposed solution is to introduce a static_printf, a compile-time version of printf. Output is directed to the compiler's stdout, just as the message for a static_assert is upon failure, but utilising printf formatting. It has no effect on the output binary (except in the case of a formatting error).

To output a formatted message and render a program ill-formed, static_assertf is proposed too. It's just like static_assert but with printf-style formatted messages. There's a 'future considerations' section which touches on the potential use of std::format in future if it heads down the constexpr route.

The main use cases of static_printf are to help with debugging template metaprogramming from a user perspective, and to allow library authors to provide a better user experience. Other uses are: reducing the compile-time learning curve (and giving newcomers to compile-time C++ a "hello world"), and allowing some build metrics to be provided with standard C++ code - without relying on compiler extensions or nonstandard code.

I've attached a (very) rough draft. I also have some specific questions.

  1. The general idea?
    What do you think?

  2. The naming
    I've chosen static_printf to keep in line with the name "static_assert". I've chosen "static_assertf" in respect of the reasonably common "assertf" idiom in C. I believe the naming is appropriate, but if you think otherwise please let me know.

  3. The technicalities
    I've specified that static_printf and static_assertf are declarations, which I believe to be appropriate. I've stated that a format error within an evaluated static_printf should render the program ill-formed. std::printf results in undefined behaviour if the format is invalid, but with static_printf all of the necessary information is already available. Is this appropriate?

  4. Anything I should remove?
    Many proposals are more concise and get to the proposed changes after a rather short introduction. This is often when addressing a well-known problem. In some conversations I've had about this, it isn't always apparent that the string literal restriction of static_assert is a problem until examples are provided (sometimes not even then - you win some, you lose some). To address that, I've added what I believe are illustrative examples where static_assert isn't particularly useful. Is this unnecessary?

  5. What's missing?
    I'm aware I'll need to add a "proposed changes" section. That will require a bit of bookwork so I wanted to run the general idea through everyone here first. Is there anything else I should add?

Kind regards,
Jake Arkinstall