Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any implementation of type-safe, compile-time checked printf?

Tags:

c++

I saw many implementation of type-safe printf, but most of them are using exception to raise type errors.

As exercise, I implemented prototype of printf-like formatting using string literals, and it seems to solve all the problems with old, good printf family (except using format read from external source which is always not safe).

Example:

int main(int argc, char* argv[])
{
    std::cout << "const char*: %s, std::string: %s\n"_format("ONE", std::string{"TWO"});
    std::cout << "user defined: %*\n"_format(std::complex<int>{1, 2});
    std::cout << "hex: 0x%x, int: %d\n"_format(16, 123);
    std::cout << "double.2: %.2f, double: %f\n"_format(13.123123, 12.1);

    std::string s = "p(%d, %d)\n"_format(123, 234);
    std::cout << s;

//    not yet working
//    int x, y;
//    std::cin >> "p(%d, %d)"_format(x, y);
//    "p(%d, %d)"_format(x, y) = "p(999, 888)";
}

Full, dirty and not complete nor optimized code is here

Generated .s shows that no text processing is done in runtime, even if variables are not const, but taken for example from argv. Passing wrong variable type, or using argument count cause ugly compilation error, which could be improved with static asserts or concepts.

This is only exercise, and the question is: Is it any library, which supports such constructions, and why such approach is not part of c++ standard?

like image 793
ziomq1991 Avatar asked Nov 09 '17 10:11

ziomq1991


1 Answers

The {fmt} library and C++20 std::format have compile-time format string checks. For example (https://godbolt.org/z/vr57bqzb3):

#include <fmt/core.h>

int main() {
  std::string s = fmt::format("{:d}", "I am not a number");
}

gives a compile-time error because d is an invalid format specifier for a string. This uses Python-like format string syntax, not printf syntax though.

like image 190
vitaut Avatar answered Nov 15 '22 21:11

vitaut