3 ms·
But strstr() doesn't seem rotten or "legacy" in a bad way.
by crucini 10y ago
But strstr() doesn't seem rotten or "legacy" in a bad way.
- xyzzyz 10y agostrcpy() does, though.
- kazinator 10y agoWhat's wrong with strcpy? In a nutshell, we can only safely use it if we somehow know that the source string fits into the destination buffer. Those situations are few: basically, they involve fixed-length string literals being moved into buffers that are "obviously" larger. E.g. some widget_t object has a char name[256] field, and we initialize it by default with strcpy(new_widget->name, "<unnamed widget>"), or some bullshit like that. The literal is way shorter than 256 and nobody in their right mind will ever make it that long, or shorten [256] in widget_t so that this literal doesn't fit. In situations when we don't know the length of the source string, there are two cases: it is going into some buffer that is already allocated, or else we will be allocating one. In either situation, we must measure the length of the source string, to test whether it fits or to determine how much to allocate for it. In the case when the string doesn't fit into the target buffer, we cannot use strcpy, obviously, since it copies the entire string. We use some truncating-copying function, or we handle the situation in some other way (diagnose the problem and abort or whatever). In the case when we allocate, because we have calculated the length, we still should not use strcpy to finally copy the string. We should use memcpy, because memcpy doesn't wastefully examine every byte to see whether it is null. So the opportunities for a correct, non-wasteful use of strcpy are few.
- kd5bjo 10y agoYou're correct about the problems, and I would always recommend strncpy over strcpy for safety, but it's not quite as limited as you portray: You only need to ensure an upper bound on the string length that will fit into your destination buffer. In addition to literals, this can also be guaranteed by copying a string that's already stored in a container that's smaller than the target, such as a fixed-size buffer or database field.
- kazinator 10y agostrncpy is strcpy's daft cousin that wastefully writes extra null characters---except when there is no room; then it neglects to null-terminate at all. strncpy was not needed even in C90, because of sprintf, which is less clumsy to use, doing everything in one step: char array[64]; sprintf(array, "%.63s", some_string); If we replace the 63 with * , we can pass a dynamic size: sprintf(array, "%.*s", (int) sizeof array - 1, some_string);
- gohrt 10y agogets() is the worst http://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used http://stackoverflow.com/questions/1694036/why-is-the-gets-f...
- kazinator 10y agoPeople say that gets is fundamentally broken as an API, beyond repair. However, gets could have been "rescued" in C by requiring every implementation to publish a constant, say in <limits.h>, which indicates a maximum of how many bytes (including null terminator) the gets function will place into the target buffer, and ensuring that gets observes this constant. Indeed, evidently, there was talk of this, and supposedly Doug Gwyn proposed that simply BUFSIZ be re-used for this purpose. With such a constant in place, programs using gets could be wrenched out of the jaws of undefined behavior by sizing the input array according to that constant, ensuring that there cannot be overflow. Rather than introducing this requirement, in the end the function was simply removed from the language.