4 ms·
If we preset the end of buffer with '\0' and then assume the buffer having 1-less capacity, wouldn't it address the strncpy issue?
by hzhou321 8y ago
If we preset the end of buffer with '\0' and then assume the buffer having 1-less capacity, wouldn't it address the strncpy issue?
- needlepont 8y agoOf course, but everyone wants to overdo the complexity of the time worn solution. OMG you need to null terminate the string after all the _other_ gymnastics..gee C sure does suck! Why don't we use rust|go|c++ ad-nauseam. bzero(buf,sz); /memset nazis here/ strncpy(buf,src,sz - 1);
- bitwize 8y agoIt doesn't make sense to have to null-terminate the string by hand (maybe) after doing a "safe" STRING copy. Which means it's easy to forget to do and that's a dangerous wart in the design. Really, stop using C. To quote Hayao Miyazaki, C was a mistake.
- needlepont 8y agoTeach your grandmother to suck eggs and resign the thought police please.
- dang 8y agoPosting like this will get you banned here. Please review and follow the rules: https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html.
- hzhou321 8y agoWhat I meant is more like: #define BUFSIZE 100 char buf[BUFSIZE+1] buf[BUFSIZE]=0 // for global var, it is already zeroed, right? Then one can call strncpy(buf, BUFSIZE, ...) without worrying about null-termination.
- sevensor 8y agoWell, again, you have to assume that the caller called you right, i.e. that the pointer you were passed points to a buffer with exactly one zero in it, at the end. Furthermore, unless there's also a (potentially wrong) length argument, you have to read every byte of the destination buffer while you're copying and stop when you see a zero. There's a lot to be said for a reimplementation like bstrlib that wraps char arrays in structs and gives you replacements for most of the string functions, but then you still have all these C APIs to deal with that use char*. And you have the overhead of trying to do things right at runtime. Sibling comment mocks languages that do compile-time safety checking, but I totally see the appeal.
- hzhou321 8y agoI am not sure I follow the extent of the problem. With `strncpy`, the caller assumes the responsibility of buffer size (by specify that size explicitly every single time. I thought that responsibility is not being debated within the current context.
- brucedawson 8y agoThat responsibility - for passing the correct buffer size - is one of the issues. I have seen many bugs where the caller simply passed the wrong size to strncpy. If you have a fixed-size buffer then the compiler can infer the size for you, thus making this class of bugs go away entirely. TL;DR - I've reviewed enough code to know that software developers pass the wrong size to strncpy and friends.
- hzhou321 8y agoSo you need a data structure (or language) that have size embedded in, and the knowledge (and restrictions) of that data structure need to spread to every libraries or function that one use (we are talking about string handling here). It appears to me that you have cornered yourself that the only solution is to modify C/C++ standards to redefine string handling. I am not saying that is bad. But solutions already exist. One is using the string class, another being transiting to a dynamic language (having size as part of data structure and checking it at every usage is one step into dynamic types). Alternatively, the compiler can take over this responsibility by statically check every call (the rust solution). That is a different language. On that, I have a question: how can we pass the syntactic buffer size into a static library without embedding the size into the data? If we do embedding the size, then it is still dynamic within the context of the library. Either way, one should not still be discussing the safety of strncpy here. Now as long as we are discussing strncpy, I assume it is given that we do not want to have buffer size as permanent part of the simple string type and we are not looking for any solutions that demand an overhaul of the language/libraries. I assume it is given that caller takes the responsibility of buffer size -- exchange with a bit responsibility for simpler system and greater control. You won't have a good solution (or good discussions) without confining our context first.