Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: Append with sprintf

Reply
Thread Tools

Re: Append with sprintf

 
 
Tom St Denis
Guest
Posts: n/a
 
      06-04-2010
On Jun 4, 5:31*am, "Guillaume Dargaud"
<(E-Mail Removed) t> wrote:
> Hello all,
> this is something I commonly do, but I have a nagging doubt that it may not
> be correct and/or dangerous in some situations:
>
> // Append
> sprintf(Str, "%s (Id=%d, Pnl=%d)", Str, Id, Pnl);
>
> I know from experience (and _some_ sense of logic) that the following is a
> no-no:
> // Prepend
> sprintf(Str, "(Id=%d, Pnl=%d) %s", Id, Pnl, Str);
>
> Comments ?


Why hasn't anyone suggested that at the very least you should be using
snprintf not sprintf....

Tom
 
Reply With Quote
 
 
 
 
Tom St Denis
Guest
Posts: n/a
 
      06-04-2010
On Jun 4, 7:56*am, Richard Heathfield <(E-Mail Removed)> wrote:
> Tom St Denis wrote:
>
> <snip>
>
> > Why hasn't anyone suggested that at the very least you should be using
> > snprintf not sprintf....

>
> Perhaps he doesn't /have/ snprintf.
>
> sprintf is perfectly safe if used correctly.


So is gets...

If by used you mean by the user...

snprintf is fairly ubiquitous even MSVC has it (though under a diff
name).

Tom
 
Reply With Quote
 
 
 
 
Ike Naar
Guest
Posts: n/a
 
      06-04-2010
In article <(E-Mail Removed)>,
Richard Heathfield <(E-Mail Removed)> wrote:
>Perhaps he doesn't /have/ snprintf.


That's possible, though all C99 compilers and many C89 compilers have snprintf.

>sprintf is perfectly safe if used correctly.


True, but sometimes it's much harder to use sprintf correctly than to
use snprintf correctly. Here's a simple example:
for double d and char buf[64],

sprintf(buf, "%p %f", (void*) &d, d);

Is it safe? It might be, depending on how pointers are formatted, and
depending on the value of d; or else it might cause a buffer overflow.

With snprintf it's not difficult to check:

if (snprintf(buf, sizeof buf, "%p %f", (void*) &d, d) < sizeof buf)
{
/* correct, go on */
}

Without snprintf, the check would be much, much more elaborate,
for instance, writing the output to a temporary file using fprintf
and counting the number of bytes in the file.
--
http://www.velocityreviews.com/forums/(E-Mail Removed)
SDF Public Access UNIX System - http://sdf.lonestar.org
 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      06-04-2010
On Jun 4, 9:39*am, Kenneth Brody <(E-Mail Removed)> wrote:
> On 6/4/2010 6:46 AM, Tom St Denis wrote:
>
>
>
>
>
> > On Jun 4, 5:31 am, "Guillaume Dargaud"
> > <(E-Mail Removed) t> *wrote:
> >> Hello all,
> >> this is something I commonly do, but I have a nagging doubt that it may not
> >> be correct and/or dangerous in some situations:

>
> >> // Append
> >> sprintf(Str, "%s (Id=%d, Pnl=%d)", Str, Id, Pnl);

>
> >> I know from experience (and _some_ sense of logic) that the following is a
> >> no-no:
> >> // Prepend
> >> sprintf(Str, "(Id=%d, Pnl=%d) %s", Id, Pnl, Str);

>
> >> Comments ?

>
> > Why hasn't anyone suggested that at the very least you should be using
> > snprintf not sprintf....

>
> Is snprintf() safe in either of the above cases? *Why replace one form of UB
> with another?


"at the very least" ...

I wasn't commenting on the UB [I'd never write either form] just
saying at the very least sprintf should go the way of gets().

Tom
 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      06-04-2010
On Jun 4, 12:02*pm, Richard Heathfield <(E-Mail Removed)> wrote:
> If it's under a different name, it isn't snprintf.


Could just as easily do a

#ifdef MSVC
#define snprintf _snprintf
#endif

zomg that's unpossible.

Sometimes, just sometimes, I have to side with the local riff-raff in
calling you out on your stupid replies. Encouraging people to use
sprintf() is just playing with fire.

Tom
 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      06-04-2010
On Jun 4, 3:11*pm, Richard Heathfield <(E-Mail Removed)> wrote:
> Tom St Denis wrote:
> > On Jun 4, 12:02 pm, Richard Heathfield <(E-Mail Removed)> wrote:
> >> If it's under a different name, it isn't snprintf.

>
> > Could just as easily do a

>
> > #ifdef MSVC
> > #define snprintf _snprintf
> > #endif

>
> > zomg that's unpossible.

>
> Ugly, but possible - *provided* snprintf is available, under some name
> or another, on all target platforms, with the same semantics on each.
>
> > Sometimes, just sometimes, I have to side with the local riff-raff in
> > calling you out on your stupid replies.

>
> If your compiler has snprintf and portability is of no consequence, by
> all means use snprintf. But that is not an assumption that I like to
> make when giving general replies. If you think that's stupid, well,
> that's your prerogative.
>
> > Encouraging people to use
> > sprintf() is just playing with fire.

>
> Which is better - to be *able* to use sprintf safely (by learning and
> practice), or to rely on the availability of snprintf? I suspect that we
> would answer that question very differently. You are entitled to call my
> answer stupid, of course, but you really, really wouldn't like to hear
> what I think of your answer.


I'd rather "deal with" the portability issues of using snprintf on the
few targets left that don't support it then use sprintf throughout my
code. glibc/ulibc are fairly common place, so really there are only
few places of ACTIVE development without snprintf handy [I'm sure on
your VAX in your basement using a copy of UNIX from 1974 there is no
snprintf, but I'll be damned if I'm developing on that platform
ANYTIME in my lifetime, nor are any of my customers...].

For ref: windows does have an snprintf function it's works just like
snprintf, it's just not CALLED snprintf. Hence my comment about the
macro.

Tom
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      06-04-2010
On 2010-06-04, Richard Heathfield <(E-Mail Removed)> wrote:
> Which is better - to be *able* to use sprintf safely (by learning and
> practice), or to rely on the availability of snprintf? I suspect that we
> would answer that question very differently. You are entitled to call my
> answer stupid, of course, but you really, really wouldn't like to hear
> what I think of your answer.


Given that snprintf has been written portably under terms which allow
its inclusion in commercial code, I would say that relying on the availability
of snprintf (but being prepared to provide it if you're using an old compiler)
is probably a better choice.

Even with a great deal of experience, it's possible to screw up sprintf in
a variety of ways that snprintf won't be screwed up, and it requires more
fiddly work and provides more points of failure.

And, frankly, there are no longer any systems I care about which lack
snprintf. It's been effectively universal, for my purposes, since last
century. If there are exceptions, I've had no reason to try to target them.
The embedded vendor I work at provides it for all conceivable targets, the
desktop operating systems I use all ship with a compiler and C library
which have a working snprintf...

There are C99 features I don't try to rely on in code I think needs to be
portable. snprintf isn't one of them. It's easy enough to get an
implementation if one is really needed, and it's sufficiently useful, to
go ahead and use it.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      06-04-2010
On Jun 4, 5:05*pm, Richard Heathfield <(E-Mail Removed)> wrote:
> Tom St Denis wrote:
> > On Jun 4, 3:11 pm, Richard Heathfield <(E-Mail Removed)> wrote:
> >> Tom St Denis wrote:

>
> <snip>
>
> >>> Encouraging people to use
> >>> sprintf() is just playing with fire.
> >> Which is better - to be *able* to use sprintf safely (by learning and
> >> practice), or to rely on the availability of snprintf? I suspect that we
> >> would answer that question very differently. You are entitled to call my
> >> answer stupid, of course, but you really, really wouldn't like to hear
> >> what I think of your answer.

>
> > I'd rather "deal with" the portability issues of using snprintf on the
> > few targets left that don't support it then use sprintf throughout my
> > code. *glibc/ulibc are fairly common place, so really there are only
> > few places of ACTIVE development without snprintf handy [I'm sure on
> > your VAX in your basement using a copy of UNIX from 1974 there is no
> > snprintf, but I'll be damned if I'm developing on that platform
> > ANYTIME in my lifetime, nor are any of my customers...].

>
> Yes, that's the kind of answer I was expecting. The widespread
> availability of gcc/glibc is of course a Good Thing, but it does tend to
> lead people to the erroneous conclusion that "widespread" ==
> "ubiquitous". I've worked on a number of sites that don't have snprintf,
> or which have it with different semantics, leading to - um - interesting
> debugging sessions. I'd rather play with fire, and make sure I've got
> the right tools for dealing with fire - Nomex mat, extinguisher, phone,
> etc - so that I can keep it under control. Fire works under any
> implementation, but fnire is less available and less predictable.


I'd hardly call snprintf some obscure function. The fact that it's
not universal is just a flaw of the platforms that choose not to
support it. The thing is you should make your assumptions simple and
no simpler. I mean can you really assume all platforms support
sprintf? Let alone any formatted printing anyways?

I work in desktop/server/embedded spaces and a decent libc is a common
thing nowadays. I don't tend to work with UNIXes too much [other than
Linux] granted, but I have yet to really walk into any situation where
snprintf isn't handy.

> Yes. I've seen code littered with #if THIS_PLATFORM and #if
> THAT_PLATFORM. You can keep it.


It's not that hard to have a define in some common header somewhere.

I do this already for heap functions so I can remap them to user
supplied functions [almost always for non-hosted embedded targets].
Doing the same thing for snprintf is not that hard.

I can't believe we're actually chatting about this though. I'd rather
promote safer functions like snprintf and for the few odd targets that
don't support it work around it, then use a less safe function like
sprintf(). Sure you can code up a million lines of wrapper code for
every sprintf call to ensure you don't overwrite the buffer, or you
can write your own snprintf ONCE and include it on platforms where
snprintf is not provided...

Given that platforms for which you would use snprintf and it's not
provided would probably be running programs dealing only with integers
and strings you could probably write an snprintf function from scratch
in fewer lines of code than in all of our back-and-forth.

Best, you could put your snprintf function in what we in the industry
call a "library" and then refer to it in future projects when needed.
You could do this instead of writing custom buffer checking code for
every invocation of sprintf in every application you ever right.
[hint: if you're picking up on attitude, take a hint].

Tom
 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      06-04-2010
On Jun 4, 6:33*pm, Richard Heathfield <(E-Mail Removed)> wrote:
> Seebs wrote:
>
> <snip>
>
> > And, frankly, there are no longer any systems I care about which lack
> > snprintf.

>
> Sure. Thing is, there are more systems on this good earth than the ones
> *you* care about.


Except that not using a function like snprintf is just poor form.
It's smarter to just write your own snprintf for the platforms that
lack it, than to work around with sprintf.

Tom
 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      06-04-2010
On Jun 4, 6:57*pm, Richard Heathfield <(E-Mail Removed)> wrote:
> > Best, you could put your snprintf function in what we in the industry
> > call a "library" and then refer to it in future projects when needed.

>
> Is that right? Hey, why didn't I think of that? [Checks stretchy string
> library.] Oh look, I did.


So your solution to the non-universal nature of snprintf is to write
functions which are also non-universal?

Anyways, let's leave it be.

Tom
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Append with sprintf Ersek, Laszlo C Programming 1 06-04-2010 05:10 PM
the address of list.append and list.append.__doc__ HYRY Python 10 09-26-2007 09:41 AM
Is there a function similar to C++'s sprintf Pep Java 5 08-25-2005 08:23 PM
sprintf shea martin Java 5 09-03-2004 01:40 AM
String class, how to implement sprintf? CJ C++ 1 10-28-2003 10:54 PM



Advertisments