David Laight wrote:
probably that you were underestimating the time required to parse the format string, which is probably greater than anything else. Everything else is simple searching and copying whereas the parsing is probably at least a quadratic-order function.
No it will be linear (on the length of the format string). But just rather more expensive than you probably expect.
That's the reason that I thought it will be faster. However, since the test program copied 40 bytes 10 times, which is a rather extreme case, and still was not faster, we can only conclude that sprinf is not practical for almost all standard cases.
There is a lot of red tape lurking.
David
This, however, does not answer the usability issue. Obviously, we won't put in patches that convert to anything else just because someone didn't like it (yes, I agree with Alexander on this point). There is, however, the question of buffer overruns.
I suggest implementing strlcat and strlcpy, as in OpenBSD. I can write them, but I'm not sure where to place them. They should either be inlined (as in - implemented in an include file as a static func), or in some library that will be linked (statically, I hope). Ideas?
For those who don't know strl* functions - they are just like strn* functions, except that the parameters are sane: In strn*:
* Resulting string is not always NULL terminated. * In strncat, the terminating null is always written, but is not counted in the size!!! * The size parameter is sometimes the total size of the buffer, and sometimes the size of the unused portion of the buffer. * On strncpy, the entire buffer is written into, even if very little of it is needed (performance)
All of the above make for awkward and error prone coding. In order to use strncat properly, you have to keep subtracting the number of characters already copied, and 1 for the terminating nul. As a result of these subtractions, a negative overflow (i.e. - from 0 to maxint) may happen, which in turn causes buffer overruns itself. Unlike it, in the strl* functions:
* Resulting string is ALWAYS NULL terminated, whether there was enough room or not. * The buffer is not padded with NULLs beyond the terminating one (performance). * The number is ALWAYS the total buffer size. No arithmetics are necessary.
Shachar