linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Some question about one method.
@ 2004-05-21 10:24 Alphex Kaanoken
  2004-05-21 21:17 ` Jan-Benedict Glaw
  0 siblings, 1 reply; 9+ messages in thread
From: Alphex Kaanoken @ 2004-05-21 10:24 UTC (permalink / raw)
  To: Linux devellist

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.

Thanx.

-- 
Senior Developer of Crew IT research labs
Alphex Kaanoken <alphex@crew.org.ru>
Web: http://crew.org.ru

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: Some question about one method.
@ 2004-05-21 10:54 Ranga Reddy M - CTD ,Chennai.
  2004-05-21 21:19 ` Jan-Benedict Glaw
  0 siblings, 1 reply; 9+ messages in thread
From: Ranga Reddy M - CTD ,Chennai. @ 2004-05-21 10:54 UTC (permalink / raw)
  To: Alphex Kaanoken, Linux devellist

Hi,

char ch[1];
ch[0]=(char) sym;
ch[1]='\0';

strcat(tmp,ch);

usage of the strcat as you mentioned.
But, how fast this is going to be I have no idea.

Cheers,
Ranga

-----Original Message-----
From: Alphex Kaanoken [mailto:alphex@crew.org.ru]
Sent: Friday, May 21, 2004 3:55 PM
To: Linux devellist
Subject: Some question about one method.


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.

Thanx.

-- 
Senior Developer of Crew IT research labs
Alphex Kaanoken <alphex@crew.org.ru>
Web: http://crew.org.ru
-
To unsubscribe from this list: send the line "unsubscribe
linux-c-programming" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Some question about one method.
  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
  0 siblings, 1 reply; 9+ messages in thread
From: Jan-Benedict Glaw @ 2004-05-21 21:17 UTC (permalink / raw)
  To: Linux devellist

[-- Attachment #1: Type: text/plain, Size: 899 bytes --]

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.

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.

MfG, JBG

-- 
   Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481
   "Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg
    fuer einen Freien Staat voll Freier Bürger" | im Internet! |   im Irak!
   ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Some question about one method.
  2004-05-21 10:54 Ranga Reddy M - CTD ,Chennai.
@ 2004-05-21 21:19 ` Jan-Benedict Glaw
  0 siblings, 0 replies; 9+ messages in thread
From: Jan-Benedict Glaw @ 2004-05-21 21:19 UTC (permalink / raw)
  To: Linux devellist

[-- Attachment #1: Type: text/plain, Size: 1080 bytes --]

On Fri, 2004-05-21 16:24:23 +0530, Ranga Reddy M - CTD ,Chennai. <rangareddym@ctd.hcltech.com>
wrote in message <53BBBB3235C2C74583722B212B36CA0D61F909@vishnu.ctd.hcltech.com>:
> Hi,
> 
> char ch[1];
> ch[0]=(char) sym;
> ch[1]='\0';
> 
> strcat(tmp,ch);
> 
> usage of the strcat as you mentioned.
> But, how fast this is going to be I have no idea.

Whoops, off by one! That's a bad (read as wrong and possibly even a
security relevant bug). You declared "ch"  to be an array with one
element, that's ch[0]. So you're not allowed to assign anything to
ch[1]. If you need two bytes, just ask for that.

Remember, inside the braces you put number of elements. It's not the
highest useable index (which is one less than number of elements).

MfG, JBG

-- 
   Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481
   "Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg
    fuer einen Freien Staat voll Freier Bürger" | im Internet! |   im Irak!
   ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Some question about one method.
  2004-05-21 21:17 ` Jan-Benedict Glaw
@ 2004-05-24  8:06   ` Charlie Gordon
  2004-05-24 17:30     ` Jan-Benedict Glaw
  0 siblings, 1 reply; 9+ messages in thread
From: Charlie Gordon @ 2004-05-24  8:06 UTC (permalink / raw)
  To: linux-c-programming

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










^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Some question about one method.
  2004-05-24  8:06   ` Charlie Gordon
@ 2004-05-24 17:30     ` Jan-Benedict Glaw
  2004-05-24 23:24       ` Charlie Gordon
  0 siblings, 1 reply; 9+ messages in thread
From: Jan-Benedict Glaw @ 2004-05-24 17:30 UTC (permalink / raw)
  To: linux-c-programming

[-- Attachment #1: Type: text/plain, Size: 4015 bytes --]

On Mon, 2004-05-24 10:06:51 +0200, Charlie Gordon <gmane@chqrlie.org>
wrote in message <c8sab1$biq$1@sea.gmane.org>:
> 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.

There are sane uses of sprintf(). C is (and always was) by experts for
experts. So you've to do proper allocation anyways:)

> 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

Argh, you're right on this one. I didn't catch it :-(

> 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.

I don't - I'm totally against it now that I've seen that. I never ever
came to the idea of using a source string for destination...

[code fragments]

> 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.

I second that. C's syntax is quite simple, but only people who really
understand C's pointer and allocation concepts should use it.

> 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);

Right:)

> - 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

That's mostly sign problems/questions. (I don't think there's something
technically wrong with the enum BOOL, but you shouldn't use it except
with other enum BOOL xxx variables ...). But more interestingly:

char *a;
short *b;
int *c;
long *d;
long long *e;

--> What's the difference between a++ and e++?

struct {
	char first;
	char second;
} s1;
struct {
	char both[2];
} s2;

What's the difference:)

But to come to an end, I haven't seen the abous of tmp in the given
example...

MfG, JBG

-- 
   Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481
   "Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg
    fuer einen Freien Staat voll Freier Bürger" | im Internet! |   im Irak!
   ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Some question about one method.
  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
  0 siblings, 2 replies; 9+ messages in thread
From: Charlie Gordon @ 2004-05-24 23:24 UTC (permalink / raw)
  To: linux-c-programming

Hi JBG,

> There are sane uses of sprintf()...

There is almost no overhead to using snprintf.  And it is so difficult to
prove that a given sprintf format cannot overflow...  Just try this one:
what if ints are 64 bits now, is the buffer large enough to accomodate all
these digits ?
Yet there is much worse function : strncpy.  This sucker does NOT do what
you think it does. Pull the man page, read it, read it again... unbelievable
isn't it ? Test it, grep any source files for this buddy, I bet you'll find
subtle bugs stuck to it like fly paper.

> C is (and always was) by experts for experts.
> C's syntax is quite simple, but only people who really
> understand C's pointer and allocation concepts should use it.

I agree completely on this, programming in C is like riding down
the guardrail, except it's more like a razor blade.
It's just so hard to always keep a sharp eye for all the pitfalls one
comes across in even the simplest one liners.

I urge you to get a look at http://www.joelonsoftware.com/
I especially like his "Guerrilla Guide to Interviewing"
(http://www.joelonsoftware.com/articles/fog0000000073.html) :
"I've discovered that understanding pointers in C is not a skill, it's an
aptitude. For some reason most people seem to be born without the part of
the brain that understands pointers. This is an aptitude thing, not a skill
thing - it requires a complex form of doubly-indirected thinking that some
people just can't do."

>> - what is wrong with : enum BOOL { FALSE=0, TRUE=1 };
> (I don't think there's something technically wrong with the enum
> BOOL, but you shouldn't use it except with other enum BOOL
> xxx variables ...)

Well you are going to love this one!
defining BOOLeans TRUE and FALSE as an enum makes them available for
symbolic debugging, but you should still #define them to avoid nasty
surprises with the preprocessor:

#if TRUE
// if you don't, this code will never compile
#endif

> char *a;
> short *b;
> int *c;
> long *d;
> long long *e;
>
> --> What's the difference between a++ and e++?
it makes them point to the next element in the arrays of respective types,
and as such increments the binary value by a different amount.

More interestingly what is the difference between e[5] and 5[e] ?

> struct {
>  char first;
>  char second;
> } s1;
> struct {
>  char both[2];
> } s2;
> what's the difference ?
On most architectures, not much.  But C makes no guaranties as to the actual
layout of structures.
In particular (&s1.second - &s1.first) may be different than 1.
Similarly sizeof(s1) can be different from sizeof(s2).

Glad you found my quiz useful.

Chqrlie.

PS:) did you know about this new C library extension : imprecations
you can pass extra information to some of the C runtime APIs, thus
preventing some of the most annoying problems in C.
for example, memory allocation issues are finally solved :

p = malloc(n), "nofail";
free(p), "pack";
p = realloc(p, newsize), "nomove";

best of all, your compiler most likely already supports imprecations ;-)






^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Some question about one method.
  2004-05-24 23:24       ` Charlie Gordon
@ 2004-05-25  0:06         ` Jeff Woods
  2004-05-25  0:41         ` Glynn Clements
  1 sibling, 0 replies; 9+ messages in thread
From: Jeff Woods @ 2004-05-25  0:06 UTC (permalink / raw)
  To: Charlie Gordon; +Cc: linux-c-programming

At 5/25/2004 01:24 AM +0200, Charlie Gordon wrote:
>>char *a;
>>short *b;
>>int *c;
>>long *d;
>>long long *e;
>>
>>--> What's the difference between a++ and e++?
>
>it makes them point to the next element in the arrays of respective types, 
>and as such increments the binary value by a different amount.
>
>More interestingly what is the difference between e[5] and 5[e] ?

Since pointer addition is commutative [i.e., *(e+5) == *(5+e) ] they're the 
same thing.

My favorite C obfuscation.  (And I only use it when I intend to be obtuse! 
:)  Note below that "j" is an int and "t" is an array of char and there's a 
"putchar(j[t])" in there.  [Yes, it compiles and runs.]

--
int main(void){int j=2003;/*(c)2003 cishikawa.*/
char t[]="+<WJ> @abcdefghijklmnopqrstuvwxyz.,\n\"";
char*i="y>b<+x,m+tie@.juswndnc@dt<Wupi\"JWhysbJirviiy";
while(*i)((j+=strchr(t,*i++)-(int)t),(j%=sizeof t-1),
(putchar(j[t])));return 0;}/* under GPL */ 



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Some question about one method.
  2004-05-24 23:24       ` Charlie Gordon
  2004-05-25  0:06         ` Jeff Woods
@ 2004-05-25  0:41         ` Glynn Clements
  1 sibling, 0 replies; 9+ messages in thread
From: Glynn Clements @ 2004-05-25  0:41 UTC (permalink / raw)
  To: Charlie Gordon; +Cc: linux-c-programming


Charlie Gordon wrote:

> > struct {
> >  char first;
> >  char second;
> > } s1;
> > struct {
> >  char both[2];
> > } s2;
> > what's the difference ?
> 
> On most architectures, not much.  But C makes no guaranties as to the actual
> layout of structures.
> In particular (&s1.second - &s1.first) may be different than 1.

More generally, (&s1.second - &s1.first) is meaningless. Pointer
arithmetic is only defined when both pointers refer to elements of a
common array.

-- 
Glynn Clements <glynn.clements@virgin.net>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2004-05-25  0:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

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).