-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parse format string at compile time with constexpr to determine number of arguments #19
Comments
Sounds like a useful and interesting challange. The tricky bits would be (1) gracefully degrading for compliers without |
I had a look at this. It's fairly easy (if cumbersome) to implement a constexpr function which counts the number of format specs in a string at compile time: constexpr int countFormatSpecs(const char* str, int i, int N)
{
return
/*if*/ (i >= N-1) ? (
/*if*/ (str[i] != '%') ?
0
/*else*/ :
throw std::logic_error("Format string prematurely terminated with a '%'")
)
/*else*/ : (
/*if*/ (str[i] == '%') ? (
/*if*/ (str[i+1] == '%') ? (
countFormatSpecs(str, i+2, N)
)
/*else*/ : (
1 + countFormatSpecs(str, i+1, N)
)
)
/*else*/ : (
countFormatSpecs(str, i+1, N)
)
)
;
}
template<int N>
constexpr int countFormatSpecs(const char (&str)[N])
{
return countFormatSpecs(str, 0, N-1);
}
Unfortunately this was about as far as I got. Ideally, we'd have the following function overloads: // Usual version, with runtime format string
template<typename... Args>
void printf(const char* fmt, const Args&... args)
{
// ...
}
// Version for compile time checking of format string (invalid C++)
template<int N, typename... Args>
void printf(constexpr char (&fmt)[N], const Args&... args)
{
static_assert(countFormatSpecs(fmt) == sizeof...(args));
// ...
} However, there's no such thing as a Having said that, it might still be possible to achieve a syntax like printf(FMT("foo %d"), 100); which could indeed be useful if you were using tinyformat via a logging macro. Of course, In all this, it's worth keeping in mind that |
Here's an amusing thought... we could likely implement this with nice syntax if we were willing to use macros 😬 For example format_("foo %d", 100);
// expand to something like
format(check_format("foo %d", 100), 100); where |
With constexpr it seems to be possible to parse the format string at compile time to determine if the number of arguments passed actually matches the number of arguments specified.
This could fill the void when moving from built-in printfs that have compile support (via attribute).
Links:
http://akrzemi1.wordpress.com/2011/05/11/parsing-strings-at-compile-time-part-i/
http://abel.web.elte.hu/mpllibs/safe_printf/
The text was updated successfully, but these errors were encountered: