Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



strncpy 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.


Then there are strn*_s since C11 (and available before that on many platforms) which do exactly what you want.


Lol 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.


>sizeof dst

Note that this only works if dst is a stack allocated(in the same function) array and not a char *


> 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.


Yes 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.


Ah, that was one of my less considered additions - thank you for the feedback!


Would 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.


Uh, 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. :)


The 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)


If you really need a fast strcpy then probably not, but in most situations snprintf will do the job just fine. And will prevent heartache.


snprintf is pretty slow, partly because it returns things people typically don't want.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: