[Effective-cpp] Item 2: The String Formatters of Manor Farm, Part 1: sprintf

Paul Grenyer paul at paulgrenyer.co.uk
Thu Oct 28 19:36:52 EDT 2004


Pal

> > There is no length safety. There is no way to explicitly limit how much
> > of the character array is used. This can and often does result in buffer
> > overrun errors.
>
> No length safety is a prblem everyone shall be aware.

Shall or should? :-)

> Unfortunaltely sprintf
> has no way to pass in the buffer length, and stop there.  Many
> implementations provide such safe versions (snprintf ot alike) , those are
> not standard, but I'd suggest use those instead of sprintf.
> The only way to fight the length problem with sprintf is to use large
enough
> buffer. That is easy to guess if the format specifier use width-limit for
> the elements, otherwise it is unbound for %s strings, and can trick you
with
> floating.

Have you read the item? This is all covered.

> There are tamed versions, like MFC's CString::Format().  It uses the same
> format string and argument row, just the result goes to a handled memory
> block.  The library calculates the needed length and it never overflows.

This is a nice clean list. Don't go mentioning things like the MFC. ;-)

> > There is no type safety. Errors in the format specification are not
> > caught at compile time. They're caught at run time, if you're lucky.
> > Lint tools will catch many of these problems.
>
> This point is very narrow that way.  sprintf is a ... taking function.  In
> C++ such functions are rare, and I observed the programmers are growing
> unaware of its nature.

That is probably a good thing. Are there any C++ functions that do use ...?
Or is it only function sinheritted from C?

> ... will:
>
> - take anything without a slightest warning
> - some types will suffer promotions/conversion using rules no one knows.
> (not me at least)
> - it is UNDEFINED BEHAVIOR to pass any non-pod.

More good reason not to do it!

> Yeah, if you see everyone just passing CString arguments vithout
observable
> problems does not mean it is legal -- or that some operator gets called.
No,
> CString happens to contain a single member, that is a poitner to the
string
> data.  And MSVC passes classes as a plain struct, just dumping the data on
> the stack, no ctors, or dtors called anywhere.  Anyone else thinks  it's
> overly fragile?

More to the point, does anyone really like CString? Also, I don't think it
is really relevant to the discussion as it is non-standard (hmmm...that
kinds counts boost::lexical_cast out too, but at least it works on multiple
platforms).

> To avoid the ...-related problems I created a set of type-converter
> functions and every argument is passed through them.  The functions just
do
> an implicit cast, the catch is they know the proper target type.

(snip)

Wow! Why not just use std::stringstream?

Regards
Paul

Paul Grenyer
email: paul at paulgrenyer.co.uk
web: http://www.paulgrenyer.co.uk
articles: http://www.paulgrenyer.dyndns.org/articles/

Jensen should have gone to Williams.
Ecclestone is killing the sport.




More information about the Effective-cpp mailing list