linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Charlie Gordon" <gmane@chqrlie.org>
To: linux-c-programming@vger.kernel.org
Subject: Re: Some question about one method.
Date: Mon, 24 May 2004 10:06:51 +0200	[thread overview]
Message-ID: <c8sab1$biq$1@sea.gmane.org> (raw)
In-Reply-To: 20040521211714.GP1912@lug-owl.de

On Fri, 2004-05-21 14:24:41 +0400, Alphex Kaanoken <alphex@crew.org.ru>
wrote in message <1085135081.21344.21.camel@relay.localnet>:
> Hi guys,
> I'm have a some question
> how I can change the:
> sprintf(tmp,"%s%c",tmp,sym);
> where - char *tmp;int sym;
> may I use strcat or another method.
> I need a fast and better method for do it.

Jan-Benedict Glaw commented:
> That's perfectly good in C. Why do you want to change that? It the
> length of ths ASCIIZ string pointed to by temp is known, there's a good
> chance to optimize it. However, that's against readability, so I'd
> advise against it...

I must disagree : this piece of code is NOT perfectly good in C.

1) sprintf is a nest of buffer overflow bugs waiting to bite.  The issue is
of course the size of the tmp buffer. If it is known, the code can be
optimized and that will not make it less readable, conversely, if it is not
known, then we have a real bug in front of us, as extending the string by
one character will likely overwrite whatever is next in memory.
Don't use sprintf !  use snprintf.  If you cannot use snprintf, then you are
in trouble.

2) assuming you can use the destination buffer as an argument to sprintf is
asking for trouble !  Obviously it would almost certainly fail if not used
as the first argument for a format string starting with %s : a very
restrictive case.  ISO-C is very clear about such an abuse: 7.19.6.6
Description "...If copying takes place between objects that overlap, the
behavior is undefined."  A C library that would not support it and modify
tmp before it is used as the source for %s would not be incorrect.  The
unsuspecting C newbie (and the vast majority of his elders) would not
understand why sprintf(tmp,"%s%c",tmp,sym); would "work" and
sprintf(tmp,"%c%s",sym,tmp); would "fail".
Do not encourage such ugly code.

If you know tmp will accomodate the extra character, why not use the
following code:

char *p = tmp + strlen(tmp);
p[0] = sym;
p[1] = '\0';

Or better, if you know tmp size:

int len = strlen(tmp);
if (len + 1 < tmp_size) {
    tmp[len++] = sym;
    tmp[len] = '\0';
}
// notice how len is still the length of the tmp string.

Lastly, if you do not understand the above code snipplets, you are lacking
some fundamental C concepts esp. pointers and should not undertake any
significant programming project in C.  This is just friendly advice, as
debugging it will be horribly frustrating.

JBG's concern about readability would be best addressed with a utility
function, possibly implemented inline such as:

char *strncat1(char *buf, int bufsize, int c);

Chqrlie.

PS: a few simple trick questions for C newbies :
- what is -1 ?
- what is wrong with : enum BOOL { FALSE=0, TRUE=1 };
- what is the difference between : i << 2  and i * 4
- same question for : i >> 2  and  i / 4










  reply	other threads:[~2004-05-24  8:06 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-21 10:24 Some question about one method Alphex Kaanoken
2004-05-21 21:17 ` Jan-Benedict Glaw
2004-05-24  8:06   ` Charlie Gordon [this message]
2004-05-24 17:30     ` Jan-Benedict Glaw
2004-05-24 23:24       ` Charlie Gordon
2004-05-25  0:06         ` Jeff Woods
2004-05-25  0:41         ` Glynn Clements
  -- strict thread matches above, loose matches on Subject: below --
2004-05-21 10:54 Ranga Reddy M - CTD ,Chennai.
2004-05-21 21:19 ` Jan-Benedict Glaw

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='c8sab1$biq$1@sea.gmane.org' \
    --to=gmane@chqrlie.org \
    --cc=linux-c-programming@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).