11 ms·
> printf("%s\n", "Hello, World!"); > > That's an awful lot of symbolic syntax. Well... Because it should have been printf("Hello, World!\n"); in th
by senozhatsky 7y ago
> printf("%s\n", "Hello, World!");
>
> That's an awful lot of symbolic syntax.
Well... Because it should have been
printf("Hello, World!\n");
in the first place?
One can do something like
printf("%s,%s%c\n", "Hello", "World", '!');
and claim that C is awful and that
displayln("Hello, World!");
is so much better.
- tsbinz 7y agoThis works for a literal, but the author was probably thinking of "print a string that comes from somewhere else" where you do the first thing to avoid format characters to be interpreted.
- senozhatsky 7y agoCould be. But wouldn't then displayln() require the same string placeholder? Be it "%s", or "{1}" or someting else.
- shakna 7y agodisplayln uses the massive _Generic in display_format to supply a large number of formatters automatically. [0] [0] https://gist.github.com/shakna-israel/4fd31ee469274aa49f8f9793c3e71163#file-evil_io-h-L20 https://gist.github.com/shakna-israel/4fd31ee469274aa49f8f97...
- senozhatsky 7y agoI see. So when for a char pointer one needs to do printf("%p\n", v); the Generic call must look like this displayln((const void *)v); is it really better?
- shakna 7y agodisplayln is a _Generic. All of these are valid: displayln("Hello, World!"); displayln(100); displayln(1.8); The point is, for simple things, to not have to specify how they appear. > Well... Because it should have been > printf("Hello, World!\n"); No. You don't really want to do that. If you're doing that, use puts [0] . All this requires is a modification to one string in memory and you have an injection vulnerability. [0] http://www.cplusplus.com/reference/cstdio/puts/ http://www.cplusplus.com/reference/cstdio/puts/
- temac 7y agoIf the string was in a variable, yes, but in this case most implementations will put it in a RO section.
- shakna 7y agoThat'll be depending on undefined behaviour, though, correct?
- simias 7y agoThat's not UB, that's implementation dependent, AFAIK the C standard says nothing about read-only memory. Attempting to modify a string literal is indeed UB but that would only happen if an attacker managed to attempt to modify the string, not when the program is used normally.
- shakna 7y ago> That's not UB, that's implementation dependent, AFAIK the C standard says nothing about read-only memory. If we're being pedantic, it's _unspecified behaviour_. The implementation isn't required to document how it would behave.
- shawnz 7y agoOther important security features like N^X are also not specified in the C standard either, so what's the point of worrying about just printf format strings?
- accatyyc 7y agoHow about just puts(“Hello, World!”) which has been in C since the dawn of time?
- senozhatsky 7y agoLooks even better!
- robbyt 7y agoI think this is part of the problem with the language- a fragmented set of keywords, all with slightly different behavior.
- monocasa 7y agoputs and printf aren't keywords, they're regular functions.
- paulrpotts 7y agoWell, sort of. Specifically, printf is an oddball function because it uses the varargs mechanism, and the whole format strings mechanism is inherently risky because it effectively bypasses the type system and says "trust me." Back when I was learning C, on a Mac with THINK C, misusing printf was a sure-fire way to crash the computer very quickly, especially since misaligned accesses of 16-bit or 32-bit words caused crashes. Compilers now go to a great deal of trouble to try to do additional safety and consistency checks. Don't get my wrong, I grew up using printf, and it is massively useful. But it was designed when computers were much smaller and simpler, and design tradeoffs were made back then that probably wouldn't be chosen today. So printf, along with a whole family of related functions, has been a seething mess of a security and safety hole longer than most programmers have been alive.
- monocasa 7y agoSure, but that's varargs being the special cased but, not printf (I've written printf implementations for some ebedded systems, it's always just regular C code).
- Sean1708 7y agoFirstly, I think you're taking this waaaayyyy more seriously than it was intended. Secondly double foo = 1.2; printf(foo); puts(foo); won't compile, while double foo = 1.2; display(foo); works fine. Incidentally I actually think display is the only thing on this list that is probably worth using, you could also probably extend it to accept multiple arguments relatively simply as well.
- deleted 7y ago[deleted]