8 ms·
This looks decent, but I'm (highly) opposed to recommending `strncpy()` as a fix for `strcpy()` lacking bounds-checking. That's not what it's for, it's weird an
by unwind 4y ago
This looks decent, but I'm (highly) opposed to recommending `strncpy()` as a fix for `strcpy()` lacking bounds-checking. That's not what it's for, it's weird and should be considered as obosolete as `gets()` in my opinion.
If available, it's much better to do the `snprintf()` way as I mentioned in a comment last week, i.e. replace `strcpy(dest, src)` with `snprintf(dst, sizeof dst, "%s", src)` and always remember that "%s" part. Never put src there, of course.
There's also `strlcpy()` on some systems, but it's not standard.
- masklinn 4y agostrncpy does have its odd and rare use-case, but 100% agree that it is not at all a “fix” for strcpy, it’s not designed for that purpose, and unsuited to it, being both unsafe (does not guarantee NUL-termination) and unnecessary costly (fills the destination with NULs). The strn* category was generally designed for fixed-size NUL-padded content (though not all of them because why be coherent?), the entire item is incorrect, and really makes the entire thing suspicious.
- deleted 4y ago[deleted]
- AstralStorm 4y agoThen there are strn*_s since C11 (and available before that on many platforms) which do exactly what you want.
- masklinn 4y agoLol no. These are the Annex K stuff which Microsoft got into the standard, which got standardised with a different behaviour than Windows’ (so even on windows following the spec doesn’t work) and which no one else wants to implement at all. And they don’t actually “do exactly what you want”, see for instance N1967 (“field experience with annex k”) which is less than glowing.
- mtlmtlmtlmtl 4y ago>sizeof dst Note that this only works if dst is a stack allocated(in the same function) array and not a char *
- unwind 4y agoYes it should be read as a placeholder for whatever you need to do. Could be an array inside a struct too for instance, that is quite common.
- sedatk 4y ago> and always remember that "%s" part. Never put src there, of course > Note that this only works if dst is a stack allocated array Even this "ideal" solution is full of pitfalls. The state of memory safety is so sad in the world of C.
- tmewett 4y agoAh, that was one of my less considered additions - thank you for the feedback!
- 0xbadcafebee 4y agoWould it be a sin to use memcpy() and leave things like input validation to a separate function? I'm nervous any time somebody takes a function with purpose X and uses it for purpose Y.
- masklinn 4y agoIf you really need a fast strcpy then probably not, but in most situations snprintf will do the job just fine. And will prevent heartache.
- unwind 4y agoUh, isn't using `memcpy()` to copy strings doing exactly that? The problem is that `memcpy()` doesn't know about (of course) string terminators, so you have to do a separate call to `strlen()` to figure out the length, thus visiting every character twice which of course makes no sense at all (spoken like a C programmer I guess ... since I am one). If you already know the length due to other means, then of course it's fine to use `memcpy()` as long as you remember to include the terminator. :)
- 0xbadcafebee 4y agoThe reason you would want to use memcpy would be if 1) you already know what the length is, 2) if you need a custom validator for your input, 3) you don't want to validate your input (however snprintf() is doing that), 4) if the string may include nulls or there is no null terminator. But the fifth reason may be that depending on snprintf as your "custom-validator-and-encoder-plus-null-terminator" may introduce subtle bugs in your program if you don't know exactly what snprintf is doing under the hood and what its limitations are. By using memcpy and a custom validator, you can be more explicit about how data is handled in your program and avoid uncertainty. (by "validate" I mean handle the data as your program expects. this could be differentiating between ASCII/UTF-8/UTF-16/UTF-32, adding/preserving/removing a byte-order mark, eliminating non-printable characters, length requirements, custom terminators, or some other requirement of whatever is going to be using the new copy of the data)
- saagarjha 4y agosnprintf is pretty slow, partly because it returns things people typically don't want.