Buggy versions of snprintf

I've just discovered that the C implementation I'm working with at the moment, writes one extra character in its snprintf output. The bug was difficult to find, as I use snprintf(NULL, 0, .....) to find the length in advance, so on this platform it caused a byte to be written to a null pointer, which on this platform has the effect that it locks up and restarts about 5 seconds later (running otherwise correctly in the meantime).

Now you could say that snprintf is entitled to do what it likes, because the platform doesn't purport to comply with C99. But I still don't think it's great that a platform should have a version that is at odds with a standardised snprintf. Is this very common?

Previously I had my code use the system sprintf family if they were present, and otherwise use an in-house implementation -- but now I think I should use the latter exclusively, just to avoid trouble like this cropping up.

Reply to
Old Wolf
Loading thread data ...

Intersting use of s(n)printf().

It would seem that you're stretching the use of sprintf() beyond its defined boundaries. I don't know what most implementations of sprintf do with a null target pointer but I doubt if it's good.

The effect of passing a null format string to any of the printf() functions is also interesting to contemplate.

Reply to
Everett M. Greene

No stretch at all. Its definition, from N869, follows:

7.19.6.5 The snprintf function

Synopsis [#1] #include int snprintf(char * restrict s, size_t n, const char * restrict format, ...); Description

[#2] The snprintf function is equivalent to fprintf, except that the output is written into an array (specified by argument s) rather than to a stream. If n is zero, nothing is written, and s may be a null pointer. Otherwise, output characters beyond the n-1st are discarded rather than being written to the array, and a null character is written at the end of the characters actually written into the array. If copying takes place between objects that overlap, the behavior is undefined.

Returns

[#3] The snprintf function returns the number of characters that would have been written had n been sufficiently large, not counting the terminating null character, or a negative value if an encoding error occurred. Thus, the null- terminated output has been completely written if and only if the returned value is nonnegative and less than n.
--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

If he were using sprintf(), he would be. Which, of course, is why he uses snprintf() instead. snprintf() does have defined behaviour for the case that the output string is passed in as a null pointer.

Reply to
Hans-Bernhard Bröker

Well, predictions are hard, especially where the future is concerned ;-) How could the implementors of that snprintf() know about all the features C99 might end up requiring of this function? Existence of the function snprintf() predates the C99 standard by quite a bit, and that includes different feature sets.

The compiler only has to follow the rules it claims to follow. These days, that still typically means C90 or one of its updates, and the compiler's own documentation. snprintf() is buggy only if it fails to fulfill its claims.

Reply to
Hans-Bernhard Bröker

Also wrong. From N869:

7.19.6.6 The sprintf function

Synopsis [#1] #include int sprintf(char * restrict s, const char * restrict format, ...); Description

[#2] The sprintf function is equivalent to fprintf, except that the output is written into an array (specified by the argument s) rather than to a stream. A null character is written at the end of the characters written; it is not counted as part of the returned value. If copying takes place between objects that overlap, the behavior is undefined.

Returns

[#3] The sprintf function returns the number of characters written in the array, not counting the terminating null character, or a negative value if an encoding error occurred.
--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

AFAIK the only place to get a fully complient C99 library, is to buy it from

formatting link
A source license is US$2300

Regards Anton Erasmus

Reply to
Anton Erasmus

Goes to show my lack of familiarity with the more recent standards.

The wording is a bit odd in that it says that snprintf() is equivalent to printf() when snprintf() appears to be sprintf() with an extra parameter and defined behavior for the limiting cases (n = 0, s = NULL).

Reply to
Everett M. Greene

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.