5 ms·
When it fails it leaves you with something that's not a string. It's not safe and it's not a strcpy().
by Gracana 10y ago
When it fails it leaves you with something that's not a string. It's not safe and it's not a strcpy().
- mikeash 10y agoWhen strcpy fails it results in undefined behavior. strncpy is safer. It is not safe. This article really ought to apply s/safer/safe/ and then it'll all be good.
- geofft 10y agoWhen strncpy fails it leaves you with a character array that isn't NUL-terminated. Passing that to another string-handling function is undefined behavior, because it is not a string.
- mikeash 10y agoRight, so you need to make two mistakes before you get undefined behavior with strncpy, and only one mistake to get it with strcpy. Thus, safer, but not safe.
- sirclueless 10y agoI don't agree. Any input string that violates the strcpy invariants (must be a valid null-terminated string with length <= destination buffer size) will also violate the strncpy invariants if you subsequently treat the destination buffer as a string. Since treating the destination buffer as a string is very tempting to do given that it came from a function named "str*cpy()", you've basically added another "Gotcha" to strcpy() without gaining any safety. You're basically trading one form of undefined behavior that's explicit in strcpy for another form of undefined behavior when a developer mishandles the return value of strncpy.
- mikeash 10y agoI don't get how that adds another gotcha. The scenarios in which strncpy gets you are a strict subset of the scenarios in which strcpy gets you.
- taeric 10y agoIt is the passing of the string that is undefined. You know exactly what you get from strncpy. If you thought it did something else, you were wrong. But it is fully defined. This would be like claiming that malloc is unsafe because it doesn't return a null terminated string.
- dllthomas 10y ago> This would be like claiming that malloc is unsafe because it doesn't return a null terminated string. Well, no, because this behavior is very close to the more commonly desired behavior and often indistinguishable therefrom. That makes it more of a "gotcha".
- dom0 10y agoThat's the difference between bad API design and good API design. strncpy is bad. But so are many APIs that originated in a time where arrays were zero-indexed to save one or two instructions in a compiler. (Though these are a bit younger)
- dllthomas 10y ago> That's the difference between bad API design and good API design. strncpy is bad. But so are many APIs Agreed. > arrays were zero-indexed to save one or two instructions in a compiler Actually, I find zero-indexing more consistent whenever you need to do math with the indexes.
- taeric 10y agoIs it? I expect there are many that think they can malloc a string and immediately pass it to a function to play with. I've seen it done, back when I was a TA. And thinking that strncpy will enforce a null at the end actually seems nonsensical to me. Now. I agree that it may not have at some point in my life. But this is again arguing that it is not safer than strcpy. It most certainly is. Just not completely safe. Which again, is no surprise. Why not point out that it does no checking that you passed it pointers you are allowed to write into? I mean, I get that mistakes can be made. I even agree it is not safe. However, to claim it is not safer is akin to the people that claim Java is not safer than C because example.
- mjevans 10y agoYou called it wrong. It's a primitive and gives you choices. You can either: A) call it with sizeof(target) - 1 to explicitly tell it to NOT over-write the guard byte at the end, OR B) you can add an explicit operation to always over-write the byte at the end