4 ms·
Which is a C function and not safe at all. It is easy to make your own print function in C++ that is safe and easy to use, but there is no such function in std.
by Jensson 4y ago
Which is a C function and not safe at all. It is easy to make your own print function in C++ that is safe and easy to use, but there is no such function in std.
- adamdusty 4y agoWhy are you worried about how safe printing to terminal is? Genuinely curious, I don't work in software dev.
- jasode 4y ago>Why are you worried about how safe printing to terminal is? The "type-safe" means "type-checked" by the compiler for correctness to help prevent bugs. It doesn't mean "safety-as-in-not-dangerous".
- yakubin 4y agoIn C you can use “%g” printf format string (which indicates a value of type double), and then not pass a double to it, but e.g. an int. Easy mistake to make, when changing pre-existing code. On x86 what will happen is the code will compile, but the function is going to read its argument from a floating point register instead of an integer register as it should. This: 1. Is a bug, since a completely unrelated garbage value is going to be printed. 2. Leaks the value of a register, which may be a security issue. There are still other common issues which can easily turn into vulnerabilities, leaking private process memory, when people pass untrusted strings as format strings with the intention of printing them raw. So you want a safe print to prevent trivial bugs in general, and security vulnerabilities in particular.
- __david__ 4y agoYou’re not wrong, but on the other hand, every C compiler I’ve used for the past 25 years has at least a warning you can enable for that. And you can easily add some attribute to custom functions that make use of *printf() functions under the hood to get those also type checked by the compiler. In practice that’s been good enough for me (and catches exactly the type of error you describe).
- charcircuit 4y agoUsually the warning is enabled by default
- maccard 4y agoYou're not always printing to a terminal, char buf[10]; const char* foo = "wrong?"; int res = snprintf(buf, 20, "What could possibly go %d", foo); Will compile and do... something...
- jholine 4y agoSolved problem since ages ago. error: format '%d' expects argument of type 'int', but argument 4 has type 'const char*' [-Werror=format=] You only get into trouble when you use runtime format strings (like passing a user string as first argument to printf)
- maccard 4y agoThat doesn't work on MSVC, and ignores multiple other issues with the 3 lines of code I shared (and as you correctly identified doesn't work with runtime format strings. It also doesn't work if your code isn't a textbook example of being wrong. [0] is _slightly_ more contrived but still suffers all of the exact same problems, despite all of the information being available at compile time. [0] https://gcc.godbolt.org/z/9vK3W4bYh https://gcc.godbolt.org/z/9vK3W4bYh
- gary_0 4y agoprintf() was often used for logging in eg. web servers. If there's no way of strictly checking the size/type of what's being printed (HTTP headers, say) then there are lots of tricky ways you can use it to write arbitrary memory and pwn the server. Type-unsafeness in general also just allows for hard-to-find bugs, since only certain data at runtime will introduce undefined behavior.
- stevenhuang 4y agoThere is now in C++20 https://en.cppreference.com/w/cpp/utility/format/format https://en.cppreference.com/w/cpp/utility/format/format Which is just the great https://fmt.dev/latest/index.html https://fmt.dev/latest/index.html that even c++11 projects can use.