Reputation: 5954
I want to append a string literal to destination. I can use strcat
or strncat
:
strcat(dest, "values");
Or
strncat(dest, "values", sizeof("values") - 1);
strcat
has shorter code, it looks neat.
But I wonder about their runtime performance.
Is strncat
slightly faster at runtime because there's no need to locate terminator?
Or maybe compilers could do optimization and so there is no difference?
Upvotes: 0
Views: 2831
Reputation: 154174
Is
strncat
slightly faster at runtime because there's no need to locate terminator?
char *strncat(char * restrict s1, const char * restrict s2, size_t n);
Unlikely. In general, char *strncat()
needs to locate a null character in s2
, if it exists before s2[n]
, as concatenation stop before n
characters. Of course, the
null character in s2
of strcpy(s1,s2)
needs to be found.
strncat(dest, "values", sizeof("values") - 1);
may be slower than strcat(dest, "values");
and is not safer.
Code that does not overrun the array that may truncate:
// Assuming dest is an array
strncat(dest, "values", sizeof dest - strlen(dest) - 1);
An optimization compiler is allowed to "look-inside" well known functions like the ones below and emit code that "knows" the length/size of "values". such a compiler would certainly make equivalent performance code for the 2 below as the resultant functionality is identical - in this case.
strcat(dest, "values");
// or
strncat(dest, "values", sizeof("values") - 1);
Upvotes: 0
Reputation: 44396
strcpy()
and strncpy()
(from glibc) you'll find out that both of them need to iterate over each character of src
argument.strcpy()
as it's much easier to read and maintain, and is less error-prone.Also, if there is anything that could optimize this code, I guess any decent compiler will handle that, as it seems to be quite common expression.
Upvotes: 1
Reputation: 137392
First, both strcat
and strncat
loks for the null terminator, the difference is that strncat
also check for the size of the copied data, and will copy only n
bytes.
Second, since strcat
does not check for the size of the copied data, and copies until it gets to a null terminator, it might (and will!!) cause a buffer overflow, overriding data that is stored in memory after the buffer you copy to.
Third, your usage of the strncat is not safer, as you limit the copy by the size of the source buffer, not the destination buffer. E.g. to use it correctly you should pass the size of the destination buffer:
strncat(dest, "values", sizeof(dest) -1 );
Fourth, if the size of the source string is bigger than than n
of the destination, a null terminator will not be appended, so after the call to strncat
you should add it yourself:
strncat(dest, "values", sizeof(dest) -1 );
dest[sizeof(dest) - 1] = '\0';
Last thing, since this is strncat, and it copies to wherever the destination string terminates, the size calculation is slightly more complex and is actually:
strncat(dest, "values", total_size_of_dest_buffer - strlen(dest) - 1 );
Upvotes: 2