spinoza1111said:
Context restoration:
FG: "snprintf does not have that problem and can even be used to find
out the size of the buffer you do need."
EGN: "(Sigh). How do you know the size of the "buffer" you do need?"
RM: "Please provide an example where the programmer doesn't know the
size of the string that he must pass to snprintf()."
So this isn't about having control over the length of strings. It's
about knowing how big to make a buffer.
Presumably because you can't.
since if you had any real experience,
Yet another insult, and yet again it's poorly targeted. The issue is
finding the buffer size for an snprintf call, which - as you appear
to have learned rather belatedly - can be discovered by calling
snprintf.
This changes sprintf's semantics, as I've pointed out to Mr. Dik
Winter, because if you use snprintf to determine the size needed (or
use sprintf for that matter) you look at parameters more than once.
This isn't usually a problem since in a sense "all" parameters in C
are passed by value (which doesn't mean that there isn't an explicit
call by reference, although you can't seem to get this). Copies of all
values passed are immutable on the stack, immutable that is outside
the program doing the sprintf.
However, in a multithread environment where strings are passed by
reference (that is, their address is passed by value), whenever you
evaluate snprintf to do your own sprintf, the target strings could
change unless you call them inside a lock. This lock will pin these
strings down for an unpredictable length of time, and this may create
problems in multithread applications that depend on locks using a
constant time.
If a function is passed as a parameter, things will be worse. The
function may return different values and have different state
depending on how many times you call snprintf or printf while you're
figuring out how to do the sprintf you want. This will be twice if you
call snprintf.
You're the C expert. If the function is passed in the call it is
evaluated, its value is stacked, and there's no problem. But isn't it
also possible to pass the address of the function, and "dereference"
this inside mySprintf?
The solution is to ignore snprintf and instead call sprintf for each
parameter of yourSprintf() function, using varargs and testing strings
to see if they'll blow your stack. This preserves the semantics of
basic sprintf since each parameter is evaluated once.
In "banks and insurance companies" you can always, I suppose, assume
all sorts of preconditions, then blame or screw your customers when
things get screwed up, much as Northern Rock's insiders screwed the
British public. But real programmers minimize assertions, and don't so
dramatically change the runtime semantics of sprintf from one pass to
two pass...or n pass.