14 ms·
I'm not a fan of strlcpy(3)
- Arch-TK 2y agoAlso relevant: https://nullprogram.com/blog/2021/07/30/ https://nullprogram.com/blog/2021/07/30/ (it references this blog post and offers good solutions)
- ktpsns 2y agoGiven how nice system programming languages we have these days, I refrain to let classic Null-terminated C-Strings entering my program. Even on embedded programming we opt-in for std::string (over Arduino's String). I am just happy to save our time in favour of having some X percentage less optimal code.
- pasc1878 2y agoDepending on your usage it is not necessarily less optimal either. You never need to walk the string to find the \0 byte. e.g. for strlen. For short strings no heap memory needs to be allocated or deallocated.
- account42 2y agoIt's really too bad though that the short string optimization capacity is neither standardized nor user-controlled.
- tialaramex 2y agoIt is seriously unfortunate that C++ managed to standardize std::string, a not-very-good owning container type, but not (until much, much later) std::string_view, the non-owning slice type you need far more often. Even if Rust had chosen to make &str literally just mean &[u8] rather than promising it is UTF-8 text, the fact &str existed in Rust 1.0 was a huge win. Every API that doesn't care who owns the textual data can ask you for this non-owning slice type, where in C++ it had to either insist on caring about ownership (std::string) or resort to 1970s hacks and take char * with zero terminated strings. And then in modern C++ std::string cares about and preserves the stupid C-style zero termination anyway, so you're paying for it even if you never use it.
- roelschroeven 2y ago> And then in modern C++ std::string cares about and preserves the stupid C-style zero termination anyway, so you're paying for it even if you never use it. I don't think this in itself is a real problem. You pay for the zero at the end, which is not much. The real cost of zero termination is having to scan the whole string to find out the size, which with std::string is only needed when using it with C-style APIs.
- wmanley 2y agoand also you have to copy (probably allocating) to get a substring.
- account42 2y agoOnly if you want a substring with separate ownership though - a string_view doesn't have to be NUL-terminated.
- jabl 2y agoIf you want to pass the string_view to some API that expects NULL terminated strings, then a copy is necessary (well, maybe is some cases you can cheat by writing a NULL in the string and remembering the original character, and then after the API call restore the character). This isn't as much a fault of a string_view type of mechanism, but rather API's wanting NULL terminated strings. Which are kind of hard to avoid on mainstream systems today, even at the syscall interface. Oh well..
- account42 2y agoSure, but the thread here was about the forced NUL-terminator in std::string and the costs associated with that. If you want a NUL-terminator (e.g. for use with a C API) then you have to pay the copy (and in the general case, allocation) cost for substrings no matter how your internal strings look (unless you can munge the original string) and std::string is exactly the right abstraction for you. But yeah, it would be nice if the kernel and POSIX APIs had better support for pointer+size strings.
- kazinator 2y agoIf someone ever has to use your stuff over FFI from a high level language, they will curse you for not just using C strings.
- gpderetta 2y agoNull terminated C strings are still terrible for FFI. Pointer and length is a better solution and it is trivially interoperable with code that uses, say, string_view.
- raverbashing 2y agoExactly this It seems C is going around in circles while everybody else has moved on No, speed and "efficiency" are not a be-all, for-all. Safety is more important than that except in very specific cases. And even in these cases there are better ways and libraries to deal with this issue without requiring the use of "official" newer C functions that seem to still be half broken There's so much fiction regarding memory issues and limited memory issues and what to do if we hit limited memory issues when in practice terminate and give up is the (often enforced by the OS) norm.
- saagarjha 2y agoI look forward to your solution to bridge these libraries to every other person’s slightly different implementation of the same library, which also has to talk to every other interface that cropped up over the last 50 years and takes null-terminated strings anyways.
- shrimp_emoji 2y agoI haven't moved on. :> C FTW! Bloated langs are cringe.
- raverbashing 2y agoHave fun playing with a chainsaw with the safety disabled
- John_Cena 2y agoHave fun playing with your Fischer Price KidSafe™ playset? >:) At some point we are just outlining in general terms what we want from a language. If C was a toolbox it is a limited number of essential tools, other languages add so many things Alton Brown would faint from the unitasking nature of them. C programmers love this. I know I do.
- raverbashing 2y agoThe "kids tool" comment is so weird. I could do pretty much whatever I wanted in (DOS) user space with Pascal. I can do pretty much whatever I want in a modern OS user space with whatever lang I prefer. "Oh but you might need C bindings" because the OS was build that way! (And with Windows/COM you might prefer a C++ bindings - just saying ;) ) > If C was a toolbox it is a limited number of essential tools C is an old toolbox where 1/3 of them is a rusty finger-remover, 1/3 is a clunky barely do nothing metal crap and 1/3 of them kinda works I'm all for a simplified set of essential tools, but not one where it's sharper on the user handle than it is on the business end bUt C iS jUsT hIgH lEvEl aSsEmBlY no it is not
- Retr0id 2y agoTIL of memccpy() https://www.man7.org/linux/man-pages/man3/memccpy.3.html https://www.man7.org/linux/man-pages/man3/memccpy.3.html To be honest, every time I need to deal with strings in C I feel like I'm banging rocks together, regardless of approach. I try to avoid it at all costs.
- Arch-TK 2y agoThe standard library string handling stuff is atrocious and it surprises me that wholesale replacement of that stuff isn't more common.
- commandersaki 2y agoI can never remember the nuances of the 50 various string functions and which shouldn't be used. What I do remember is that virtually all string problems can be solved with snprintf/asprintf.
- saagarjha 2y agosnprintf is a worse strlcpy: not only does it need to call strlen if you pass it a string parameter, it also ends up in ??? territory if the string is long enough because its return type is int.
- wruza 2y agoAh, good old “what if my string exceeds two gigabytes” dilemma.
- astrobe_ 2y agoThe printf family of functions also runs a mini-interpreter that has its cost, because its main use is interpolation (the % placeholders). Some compilers can substitute them for more efficient versions (e.g. printf without any % in the format string -> puts). I don't know if they can detect and substitute an snprintf with a "%s%s" format string.
- zokier 2y ago
- kazinator 2y agoI'm not a fan of Unix man page section numbers in parentheses. strlcpy is a stopgap, whack-a-mole solution for buffer overflows. It is rationalized by the reasoning that it does not make the program less wrong, while (probably) making it more secure. When truncation matters and you have a fixed size buffer, that buffer should be large enough in order for it to be justifiable to say that someone is misusing the application. Perhaps a tester trying to break it. Nobody’s surname needs 128+ bytes. No reasonable URL for a firmware update download needs 4096 bytes. If truncation matters, no, it does not always make sense to accept a gig of data and be ready for more. You can impose a limit. A violation of the limit is an error, treated like a case of bad input.
- saagarjha 2y agoPeople have long surnames, especially if you take multi-byte characters into account. And someone with the same mindset as you is the reason why my profile picture in Google’s employee directory never did actually show up in Safari–one of the path components ended up being a couple thousand characters long (I wonder if it was literally a base64 encoding of the image itself?)
- CoastalCoder 2y agoOut of curiosity, would you mind sharing some details about your surname? E.g., its length in its native alphabet, or its length as a UTF-8 string?
- saagarjha 2y ago$ swift Welcome to Apple Swift version 6.0 (swiftlang-6.0.0.5.15 clang-1600.0.22.6). Type :help for assistance. 1> "झा".count $R0: Int = 1 2> "झा".utf8.count $R1: Int = 6
- kazinator 2y agoNo, my reasoning does not say that a browser shouldn't handle a long URL (which is a substring of a page it has already accepted and rendered).
- hgs3 2y agoThere is also strscpy [1] which behaves like the authors use of memccpy except the former doesn’t require manually passing the null terminator as an argument. [1] https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html https://manpages.debian.org/testing/linux-manual-4.8/strscpy...
- oersted 2y agoC programmers like their overly concise naming schemes don’t they… How do you expect a user to guess the subtle differences in behavior between strncpy, strlcpy and strscpy? Sure screens were smaller before and you didn’t have autocomplete, but reaching out for documentation was also harder, and there was less of it. I guess “real programmers” memorize libc down to every detail and never use dependencies they didn’t write themselves.
- acuozzo 2y ago> C programmers like their overly concise naming schemes don’t they It's a holdover from 1970s-era linkers, many of which required each exported symbol to be unique within the first six or so characters.
- oersted 2y agoThis is helpful, thanks. And I assume that no one imagined that you would need more variants of strcpy to begin with, strncpy is a pretty good name too, and then it's hard to break the pattern. Similar situations with lots of other names. I just wish that C style used fewer single char names and hard-to-decipher acronyms. Smart programmers can't read minds either...
- JohnMakin 2y ago> How do you expect a user to guess the subtle differences in behavior between strncpy, strlcpy and strscpy? man (strxcopy)
- lanstin 2y agoIn the 90s, as a working C programmer, I would make it a practice to read thru man 2 and man 3 from time to time, as well as to read all the options for gcc. The man pages were pretty good at covering the differences, if not all the implications of the differences. And to this day I strive to minimize the dependencies of my software - any dependency you have is an essentially unbounded cost on the maintenance side. I used to sign up for the security mailing list for all the dependencies, and would expect to have to follow all the drama and politics for the depenencies in order to have context on when to upgrade and when not too. With Go I don't do that, but with Python I sometimes still do. And I've been reading the main R support email list for ever. I still think that a periodic reading of lwn.net is an essential part of being a responsible programmer. I will also say, reading the article reminds me of the terror of strings in C without a good library and set of conventions, and why Go (and presumably all other modern languages) is so much more relaxing to use. The place I worked have everything length prefixed and by the end of the 90s all the network parsing was code generated from protocol description files, to remove the need for manually writing string copying code.
- VyseofArcadia 2y agoIt is a long, time-honored tradition to attempt to improve on flawed standard library functions with equally flawed functions.
- saagarjha 2y agohttps://twitter.com/dril/status/473265809079693312 https://twitter.com/dril/status/473265809079693312
- UncleMeat 2y agoA great tweet, and often useful. But I don't think it applies well here. There is a long history of "this time, the strcpy replacement will be safe" followed by cve after cve after cve. At some point I feel that the response really should be to give up on trying to make c-style strings safe.
- Gibbon1 2y agoThe problem is the function signatures of all the improved string functions are broken. You can never write a safe string function that takes two char pointers. You really want int str_try_copy(str_buffer *dest, str_slice *src)
- saagarjha 2y agoYou are more than welcome to give up on it. Personally I feel that you can never make code that handles C strings secure. That said, people will still be using them decades from now, and it is possible to give them safer APIs. Discounting everything as "oh it can never be perfect therefore we might as well throw away any efforts to make it better" is not helpful.
- raverbashing 2y agoIf I proposed a new strxyzcpy function that only null-terminated the string when the length was not a prime number and that wiped your hard drive if the destination string, before the copy, contained the sequence 'xyz' in ascii I would be very afraid someone in the C committee would think it would be a nice idea to add it.
- BobbyTables2 2y agoIn cross platform environments, it gets horrible when one does something like: #define strlcpy strncpy
- kragen 2y agookay but that's deliberate sabotage
- saagarjha 2y agoI’m always glad to see more people coming around to the fact that memccpy is the actual function they want, not these inefficient nonstandard garbage functions that are needlessly inefficient for no reason but that everyone flocks to anyways for “security”.
- SAI_Peregrinus 2y agoI just wish it also had a src_size. As it is, if dest is bigger than src, and src isn't null-terminated, it'll read past the end of src. You can make a MIN macro and use MIN(dest_size, src_size), but shouldn't have to IMO.
- wruza 2y agoThat’s exactly my experience with most of C. You go through a history of half-assed changes and realize that you’re still halfway there in $current_year, wondering how many years will it take to fix any of these obvious flaws. Committee surely has its reasons but on the surface it seems completely non-practicing, to say the least.
- Pesthuf 2y agoAnd that's why I'm not a fan of C for writing any kind of program: Every time you need to touch a string, which is an effortless task in any semi-modern language, you aim a trillion footguns at yourself and all your users. It's also pretty telling that every article that tries to explain how to safely copy or concat strings in C, like this one, only ever works with ASCII, no attempt whatsoever to handle UTF-8 and keep code points together, let alone grapheme clusters. No wonder almost all C software has problems with non-English strings...
- saagarjha 2y agoThe code in the post does indeed have a bug if the goal is to copy UTF-8 data. However the bug is quite subtle and unlikely to occur in practice, and from your comment I suspect you don’t actually know what that problem is (because you seem to be pointing at a different issue which is actually irrelevant). Maybe you or someone else can describe what the real concern is?
- Levitating 2y agoPartially copying a 2-byte character?
- saagarjha 2y agoUTF-8 works fine if you truncate a codepoint because the encoding scheme lets you detect this. The problem is more subtle than that (hint: it involves a 1-byte codepoint).
- moralestapia 2y ago>hint: it involves a 1-byte codepoint Which is?
- saagarjha 2y ago[flagged]
- commandersaki 2y agostrlcpy() is now part of POSIX: https://sortix.org/blog/posix-2024/ https://sortix.org/blog/posix-2024/.
- ben_bai 2y agoi guess that's what spikes interest. although strlcpy was first introduced in openbsd 2.4, 26 years ago! back then as a drop in replacement for strcpy. so yeah, good things need time to adopt, no wonder it's not up-to-date tech, lol. and because of NIH-syndrome we now got lot's of strXcpy functions to choose from.
- deleted 2y ago[deleted]
- parasti 2y agoOver time, for my needs, I've gravitated back to fixed-size buffers. There are many apps where it really doesn't matter that they handle any string ever without truncation. A string is too long and won't fit? Whoops, just use a shorter one.
- acuozzo 2y agoSame here. It has become easier and more defensible to do so today with gobs of RAM, even in the embedded space (somewhat). You no longer need to worry about running out of stack space, even in a deep call-stack with each function having its own little set of buffers for strings.
- nine_k 2y agoI'd say that in general any format of variable size that does not state its length before the variable part is provoking buffer-overflow bugs. Thus such formats should be avoided in any kind of binary interop, This holds even if the total length of the data in an interaction is not known ahead of time. E.g. an audio stream can be of indeterminate length, not known when the first byte is sent over the network, but each UDP packet has a well-determined length given in the header. The length field can be made variable-size in a rather fool-proof way [1], allowing to economically represent both tiny and huge sizes. (Zip files, WAD files, etc have that info at the very end, but this is because a file has a well-defined end before you start appending to it; fseek(fp, 0, SEEK_END) can't miss.) [1]: http://personal.kent.edu/~sbirch/Music_Production/MP-II/MIDI/midi_file_format.htm#vlq http://personal.kent.edu/~sbirch/Music_Production/MP-II/MIDI...
- queuebert 2y agoNiklaus Wirth has entered the chat.
- Tuna-Fish 2y agoThere are a whole bunch of other things I dislike about Pascal, but in this one he was just undeniably correct. Worrying about 1-3 extra bytes (on the 16 and 32 bit platforms where it potentially mattered) was just not worth all the issues that null-terminated strings brought with them. My current favorite string implementations are the various compact string crates for Rust. Generally, you want a string to be able to do at least three things: - Pointer, length, capacity tuple, for heap-allocated strings, 24B on x64. - String inlined into the 24B buffer. - Pointer, length tuple where pointer points to rodata. You can do any of that and the discriminator in 24B, given the healthy assumption that all strings are shorter than 2^63. Sadly, switching costs are massive and every programming language is pretty much struck with the string they started with. Hopefully, whatever comes next can crib from smartstring or compact_str or the like.
- gumby 2y agoThere was a paper on this in the late 70s from the Cedar group at PARC. This was back when computer science papers were actual scientific papers, so full of analysis of different alogorithms' performance with counted vs delimited strings. Counted strings won hands down on anything but strings so short the length was a large percentage of overall size. Yet...since nobody reads the literature, we have all continued to suffer.
- pornel 2y agoC can add a whole alphabet if str?cpy functions, and they all will have issues, because the language lacks expressive power to build a safe abstraction. It's all ad-hoc juggling of buffers without a reliably tracked size.
- lanstin 2y agoThe types that C knows about are the types that the assembly knows about. Strings, especially unicode strings, aren't something that the raw processor knows about (as far as I know). At the machine level, it is all ad-hoc juggling of buffers without a reliably tracked size, until you impose constraints like only use length-prefixed protocols and structures. Where "only" is difficult for humans to achieve. One slip up and wham.
- pornel 2y agoC with its notion of an object, TBAA, and pointer provenance is already disconnected from what the machine is doing. The portable assembly myth is a recipe for getting Undefined Behavior. C is built on an abstract machine described in the C spec, not any particular machine code or assembly. Buffers (objects) in C already have an identity and a semantically important length. C just lacks features to keep track of this explicitly and enforce error handling. Languages exist to provide a more useful abstraction on top of the machine, not to naively mirror everything even where it is unhelpful and dangerous. For example, BCPL did not have pointer types, only integers, because they were the same thing for the CPU. That was a mess that C (mostly) fixed by creating "fictional" types that didn't exist at the assembly level.
- asveikau 2y agoI feel like this person went through an unnecessary and false tangent about how people are "afraid" of memcpy due to inexperience and missed the much more important criticism that arbitrary, naive truncation on a byte level doesn't play well with Unicode.
- aflag 2y agoDo the str* functions handle Unicode any better though? I feel like you'd want a different library for that
- ben_bai 2y agothat would be wcslcpy(3)
- asveikau 2y agoNope. Unicode correctness is much more complicated than switching char to wchar_t. Many glyphs take multiple codepoints or multiple character units in either utf-16 or utf-8. You need something like the break iterator "character" separator in ICU.
- stephencanon 2y agostrlcpy is the worst C string routine except for all the others.
- voidUpdate 2y agoWhile the article itself is interesting, could they not have picked a less... offensive word in "I'd like to point out just how schizo this entire logic is"? Like strange, or weird, or unusual
- phendrenad2 2y agoHow is it offensive?
- cess11 2y agoPerhaps in a similar way as 'paki'.
- mardifoufs 2y agoNone of those words convey the same meaning though. "Schizo" doesn't mean weird or unusual in this case. Maybe there's a better word but it really conveys a specific meaning, at least in the colloquial use of the word
- layer8 2y agoMeaning #2: https://www.merriam-webster.com/dictionary/schizophrenic https://www.merriam-webster.com/dictionary/schizophrenic Many words are used with different and derived meanings, usually disambiguated by context. For example, an offensive player is not offensive in the sense you used the word in.
- bigstrat2003 2y ago"schizo" is not an offensive word.
- EPWN3D 2y agoThe point of strlcpy(3) is not to be the world's best and most efficient string copier. It's to provide a drop-in replacement to previous, memory-unsafe string copy routines in constrained environments where you have to have bounds on stuff and might not have an allocator. If there are bugs with truncation in the resulting buffer, those are the program's bugs, and they existing before strlcpy(3) came into the picture.
- foobiekr 2y agoThis. I don't understand the objection and I spent 20 years writing C code. The reason to use strlcpy is not to _fix the bug_ but rather _to prevent the bug from turning into a crash, memory corruption, or exploit_. It also forces discipline by carrying around the length. As you say, it's also a drop-in. A truncation bug is a hell of a lot easier to debug than memory corruption.
- rini17 2y ago> It also forces discipline by carrying around the length. LOL. It does not force anything - you can mishandle source or destination buffer lengths very easily and compiler won't say anything. I sometimes wonder what kind of disaster will have to happen to make C programmers agree on a standard buffer (i.e. pointer+size) type with mandatory runtime bounds enforcement ....
- foobiekr 2y agoForce is too strong a word. Yes, it's possible someone just passes whatever, or just passes strlen(s) which is an even dumber answer.
- mafuyu 2y agoI've worked on embedded RTOS projects where we had our own strlcpy implementation - it's fine. Well, I mean, all the str functions suck because C strings, but that's exactly why sticking to a good shared set of idioms and staying organized is so important. And in C, that means manually tagging buffers with their length, no getting around that. Given that, strlcpy is less bug-prone than strncpy, simply due to requiring less lines of code to use correctly per invocation. I think a lot of the confusion in the C string discourse comes from people thinking they should rely on the NULL termination byte for string length. You really shouldn't, and if you have to do it, you need to be extra careful to check all your assertions that it will be properly terminated. Just carry around the length, and bundle it with the pointer in a struct to pass it around when it makes sense. Not the most ergonomic, but it's C, what can ya do.
- KerrAvon 2y agoTFA misses the entire point of strlcpy, which is to improve security by making your code less prone to common C programmer errors that are known causes of common exploits. The author’s suggested remedies reintroduce the potential for those vulnerabilities.
- mikewarot 2y agoIf someone could port the Free Pascal string library to C, it would solve a lot of problems with new C code. It reference counts and does all the management of strings. You never have to allocate or free them, and they can store gigabytes of text. You can delete from the middle of a string too! They're counted, zero terminated, ASCII or Unicode, and magic as far as I'm concerned. Oh... And a string copy is an O(1) operation as it only breaks the copy on modification. Edit: correct to O(1), thanks mort96
- arethuza 2y agoAs an aside: can you have an O(0) operation that actually does anything?
- mort96 2y agoIt doesn't really make sense within the context of complexity analysis as something distinct from constant-time, which is denoted with O(1). A copy of a CoW string is O(1).
- carapace 2y agoStuff that happens at compile-time is O(0) (well, technically it's amortized over the number of times you run the compiled code, eh? Huh, how does JIT compilation affect Big-O analysis?)
- dhosek 2y agoThis. Pretty much with complexity analysis, you factor out any constants and only look at the term of complexity with the highest growth rate, so you end up with 1 < ln n < n < nª < 2^n (this can be extended indefinitely by replacing the n in the last case with anything to the right of n, but in practice, these are the only ones that matter.
- mikewarot 2y agoIt copies the pointer to the data and increments the reference count. When you modify a string it checks the count and copies it prior to modification if it's not 1.
- ashvardanian 2y agoAside from the NULL-termination requirements there is arguably another big design issue with libc strings. I believe the interfaces that may allocate memory - must give you an opportunity to override the allocator. Aside from the SIMD implementation quality and throughput on Arm, that was one of the key reasons to start a new library: https://github.com/ashvardanian/StringZilla/blob/91d0a1a02faae90a41c60a30855d5935eb3eaef1/include/stringzilla/stringzilla.h#L317 https://github.com/ashvardanian/StringZilla/blob/91d0a1a02fa... Also not a huge fan of locale controls and wchar APIs :)
- ComputerGuru 2y agoI’m late to the party but this mostly rehashes already voiced concerns with all the existing “updated” strcpy functions. But what I was surprised to learn is that strdup wasn’t part of the C language spec (until now)!
- pton_xd 2y agoThe main issue, which the article covers, is that there's really two different operations you want with copying C strings. Do you want to copy and truncate, or just copy? Within that, do you want to manage your own allocation, or do you want that abstracted? There's too many decision points and tradeoffs to just neatly hide behind a single "one true function" for copying C strings.
- bruce343434 2y agoIs it bad that for all application uses, I reach for `asprintf`? As well as reaching for the %ms format for scanf for reading input. For buffers, I use memcpy and length tracking. Any other approach seems like unnecessary headache. Or maybe modern hardware has spoiled me?
- coding123 2y agoReal men use memcpy
- mjevans 2y agoIf you know the length (and that it fits) mempcpy() , then add the terminator yourself to be sure. memcpy has the slightly annoying flaw of returning a copy of the dest argument (already known data) rather than the more useful new information of a pointer to the end of the set memory. #IFNDEF _GNU_SOURCE #DEFINE mempcpy(X, Y, Z) (void *)((memcpy(X, Y, Z) - 1) + Z) #ENDIF // Not quite the same but close enough mempcpy, fails for Z = 0 edited: Since X shouldn't be NULL and thus not 0, apply the subtraction first to avoid the corner case (which also shouldn't happen given common HW / OS regions) of X + Z > (~(size_t)0) (SIZE_MAX)
- mjevans 2y agoI remembered the return value incorrectly. It's even better in that it returns a pointer to the byte immediately AFTER the last written. So remove the - 1. PS: there's also a version which works with wchar_t types (be it 2, 4 or whatever else) #DEFINE mempcpy(X, Y, Z) (void *)(memcpy(X, Y, Z) + Z) #DEFINE wmempcpy(X, Y, Z) (void *)(memcpy(X, Y, Z * sizeof(wchar_t)) + Z * sizeof(wchar_t))
- strgtwhtmle 2y ago[flagged]
- snitty 2y ago"I like all my string copy's equally." CUT TO: "I'm not a fan of strlcpy(3)"
- forrestthewoods 2y agoC's string handling is an abomination. Null terminated strings is and always has been a colossal mistake. The C standard and operating systems need to be updated such that null-terminated strings are deprecated and all APIs take a string_view/slice/whatever struct.
- uecker 2y agoHere is my attempt at strings in C (and other stuff). https://github.com/uecker/noplate https://github.com/uecker/noplate (attention: this is experimental and incomplete for trying ideas and is subject to change.)
- giomasce 2y agoIt's not very clear to me why in paragraph "Truncation matters" it is claimed that the strlen variant is necessarily better than the strlcpy variant. the strlcpy variant only scan the source and destination string once in the fast case (no reallocation needed), while the strlen variant needs to scan the source string at least twice. I guess in the common case you have to enlarge the destination a few times, then once it's big enough you don't have to enlarge it anymore and always hit the fast case, os it makes sense to optimize for that. It might also be that in some programs with different access patterns that doesn't happen and it makes sense to optimize for the slow case, sure, but the author should acknowledge that variability instead of being adamant on what's better, even to the point of calling "schizo" the solution it doesn't understand. In my experience the pattern of optimizing the fast path makes a lot of sense. BTW, the strlcpy/"schizo" variant could stand some improvement: realloc() already copies the part of the string within the original size of the buffer, so you can start copying at that point. Also, once you know that the destination is big enough to receive a full copy of the source you can use good old strcpy(). Cargo cult and random "linters"/"static checkers" will tell you shouldn't, but you know that it's a perfectly fine function to call once you've ensured that its prerequisites are satisfied.
- deleted 2y ago[deleted]
- ezekiel68 2y ago> In other words, there's nothing "improper", "bad practice", "code-smell" or whatever with using the mem* family of functions for operating on strings, because strings are just an array of (null-terminated) characters afterall. So refreshing to see a common-sense take in a world of shrill low-level programming alarmists.