4 ms·
Unfortunately C is locked into null-terminated strings, given that all the printf-style functions work on the assumption there'll be a null terminator. C++ has
by williamvds 5y ago
Unfortunately C is locked into null-terminated strings, given that all the printf-style functions work on the assumption there'll be a null terminator.
C++ has std::string_view which is pointer + length, but you've still got the same problem if you need to call older printf-style functions.
- AlexanderDhoore 5y agoNope, printf can print strings without NULL-terminator: printf("%.*s", <int>length, <char*>string);
- OskarS 5y agoAnd the first argument to printf (the format), what kind of string is that? And what kind of string does sprintf() produce?
- TazeTSchnitzel 5y agosprintf tells you how many characters it has written, so there's no reason you can't use it for non-null-terminated strings.
- comfydragon 5y agowilliamvds's point is that the first argument to printf is still itself a null-terminated string, so it's basically turtles all the way down if you're using the C standard library.
- TazeTSchnitzel 5y agoTheir comment talked about two things, and the sibling comment addressed the other one.
- 10000truths 5y agoIn practice, it is almost always a compile-time-known string. gcc will warn you if it isn't, especially since allowing the use of untrusted input for the format can lead to vulnerabilities: https://en.wikipedia.org/wiki/Uncontrolled_format_string https://en.wikipedia.org/wiki/Uncontrolled_format_string
- tialaramex 5y agoAnywhere that this format is a variable, you probably already screwed up. C allows that, but if I see it that's getting flagged in my review. So long as the format string is a literal you needn't care how it works. Now, one of the places where C makes this nastier than it needed to be is that C built-in types are silly, and so any non-trivial program is using better fundamental types like uint32_t (or the more succinct u32), for which the built-in formatter offers no syntax. So you end up writing format strings like "There are "PRIu32" dogs\n" using macros to bring in the appropriate specifier for your literal. Blergh.
- nicoburns 5y agoWhy do you have to use printf? You could have a string library would could with it's own formatting routines. There's also the option of using both a length AND a null terminator.
- codesections 5y ago> There's also the option of using both a length AND a null terminator. I first encountered that idea in this classic Joel on Software post, which rather put me off the idea of using them in production: > Notice in this case you’ve got a string that is null terminated (the compiler did that) as well as a Pascal string. I used to call these fucked strings because it’s easier than calling them null terminated pascal strings but this is a rated-G channel so you will have use the longer name. https://www.joelonsoftware.com/2001/12/11/back-to-basics/ https://www.joelonsoftware.com/2001/12/11/back-to-basics/
- slavik81 5y agoJoel's article is a bit long in the tooth. As of C++11, std::string is required to use both a length and a null terminator. With the short string optimization, it could even have that exact layout. > Lazy programmers would do this, and have slow programs char* str = "*Hello!"; str[0] = strlen(str) - 1; Modern compilers understand strlen, and will replace the function call with a constant where possible. That code's not slow anymore: https://godbolt.org/z/Kjh8b44Kf https://godbolt.org/z/Kjh8b44Kf
- codesections 5y agoThat's good to know, thanks. But Joel was talking about C rather than C++, where your comments about std::string wouldn't apply, right?
- legulere 5y agoIf you are programming C, you will already roll your own data structures. So why not roll your own formatting routines?