C++ Logo

std-proposals

Advanced search

static_printf and static_assertf: Standardizing Compilation-Time Output

From: Jake Arkinstall <jake.arkinstall_at_[hidden]>
Date: Tue, 19 Jan 2021 20:05:24 +0000
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

Received on 2021-01-19 14:05:40