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
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