Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.c

Reply
 
Thread Tools Display Modes
  #16 (permalink)  
Old 02-17-2012, 11:19 AM
Malcolm McLean
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On Feb 16, 10:20*pm, Keith Thompson <ks...@mib.org> wrote:
>
> I suspect that strncpy() is used incorrectly, under the assumption
> that it's a "safer" strcpy(), more often than it's used correctly.
> IMHO it shouldn't be in the standard library, at least not with
> that name.
>

You're right.
There's no point providing strncpy() but not functions like hash() and
faststrncmpwithtrailingzeros() to actually use fixed width strings.
--
Malcolm's website
http://www.malcommclean.site11.com/www


Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #17 (permalink)  
Old 02-17-2012, 02:04 PM
James Kuyper
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On 02/17/2012 07:19 AM, Malcolm McLean wrote:
> On Feb 16, 10:20�pm, Keith Thompson <ks...@mib.org> wrote:
>>
>> I suspect that strncpy() is used incorrectly, under the assumption
>> that it's a "safer" strcpy(), more often than it's used correctly.
>> IMHO it shouldn't be in the standard library, at least not with
>> that name.
>>

> You're right.
> There's no point providing strncpy() but not functions like hash() and
> faststrncmpwithtrailingzeros() to actually use fixed width strings.


What would be the benefits of using faststrncmpwithtrailingzeros()
rather than memcmp() be?
--
James Kuyper
Reply With Quote
  #18 (permalink)  
Old 02-17-2012, 05:27 PM
Malcolm McLean
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On Feb 17, 3:04*pm, James Kuyper <jameskuy...@verizon.net> wrote:
>
> What would be the benefits of using faststrncmpwithtrailingzeros()
> rather than memcmp() be?
>

That's a point. It documents that you're doing a string compare, but
actually it's the same as memcmp(). On most platforms, it will need
guaranteed integer-aligned fields to be fast, however. That's not
something it's easy to specify in the C standard.
--
Vist my website. Play the Alice in Wonderland Card game
http://www.malcommclean.site11.com/www

Reply With Quote
  #19 (permalink)  
Old 02-17-2012, 06:22 PM
Malcolm McLean
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On Feb 17, 3:04*pm, James Kuyper <jameskuy...@verizon.net> wrote:
>
> What would be the benefits of using faststrncmpwithtrailingzeros()
> rather than memcmp() be?
>

If you have long fields with mainly short contents, it could also be
faster, since it can terminate at the first pair of nul bytes.
Reply With Quote
  #20 (permalink)  
Old 02-17-2012, 06:40 PM
James Kuyper
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On 02/17/2012 02:22 PM, Malcolm McLean wrote:
> On Feb 17, 3:04�pm, James Kuyper <jameskuy...@verizon.net> wrote:
>>
>> What would be the benefits of using faststrncmpwithtrailingzeros()
>> rather than memcmp() be?
>>

> If you have long fields with mainly short contents, it could also be
> faster, since it can terminate at the first pair of nul bytes.


If you know that the the end of the string will be determined either by
the end of a fixed-length field, or by a terminating null character,
strncmp(). If you want to check the entire length of the fixed length
field, regardless of null terminators, memcmp() would do. I don't think
that there's sufficient need for a function whose behavior falls
between those two extremes, to make it a standard library function.
--
James Kuyper
Reply With Quote
  #21 (permalink)  
Old 02-18-2012, 09:17 AM
Malcolm McLean
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On Feb 17, 7:40*pm, James Kuyper <jameskuy...@verizon.net> wrote:
>
> If you know that the the end of the string will be determined either by
> the end of a fixed-length field, or by a terminating null character,
> strncmp(). If you want to check the entire length of the fixed length
> field, regardless of null terminators, memcmp() would do. I don't think
> that there's sufficient need for *a function whose behavior falls
> between those two extremes, to make it a standard library function.
>

The main issue is usually that reading chars byte by byte is slow,
reading words is fast.

So if fields are guaranteed to be memory aligned, and a whole number
of words, a comparison will be certainly four times and often many
more times as fast as a byte by byte compare of unaligned strings of
arbitrary length. Aligned fields of whole word size are quite easy to
achieve at a low level, but difficult to specify in ANSI standard C.

Malcolm's website
http://www.malcolmmclean.site11.com/www





Reply With Quote
  #22 (permalink)  
Old 02-19-2012, 07:04 PM
Joe keane
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

In article <lnvcn6fyi2.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
>There's rarely *any* reason to use strncpy(). It's not a "safer"
>version of strcpy(); it's a quite different function.


It is a safer version of 'strcpy'. There is the issue of what to do if
the full copy can't be done, but that's program logic and the library
function can't read people's minds. Even if the program just calls
'abort', that's a huge improvement.
Reply With Quote
  #23 (permalink)  
Old 02-19-2012, 07:33 PM
Keith Thompson
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

jgk@panix.com (Joe keane) writes:
> In article <lnvcn6fyi2.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
>>There's rarely *any* reason to use strncpy(). It's not a "safer"
>>version of strcpy(); it's a quite different function.

>
> It is a safer version of 'strcpy'. There is the issue of what to do if
> the full copy can't be done, but that's program logic and the library
> function can't read people's minds. Even if the program just calls
> 'abort', that's a huge improvement.


Did you not read my description of what strncpy actually does, or do you
disagree with it?

strncat is a "safer" version of strcat. It takes an extra argument
"n" that specifies the maximum number of characters to be copied. If
the source is longer than n characters, it appends just n characters.
It properly zero-terminates the destination in all cases.

strncpy *looks* like it should be to strcpy as strncat is to strcat,
but it isn't. If the source string is shorter than n characters,
it will pad the destination with multiple null characters, something
that strcpy never does. If the source string is longer than n
characters, it will leave the destination unterminated (i.e.,
not a string).

If it had been defined something like this:

char *better_strncpy(char *dest, const char *src, size_t n) {
dest[0] = '\0';
return strncat(dest, src, n);
}

then it would be reasonable to call it a "safer" version of strcpy.

(It's possible I have an off-by-one error in the above code;
I haven't taken the time to check.)

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply With Quote
  #24 (permalink)  
Old 02-20-2012, 08:25 PM
Joe keane
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

In article <lnboouef7m.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
>strncpy *looks* like it should be to strcpy as strncat is to strcat,
>but it isn't.


Well there is a number of options.

a) should it make sure there is a zero terminator
b) maybe you want to clear everything that isn't copied
c) does it handle overlapping copies

Do i think it's slightly stupid that they don't match? A little bit.
But one can imagine that good choices were made, and that consistency is
sometimes negative.

Why does 'puts' add a newline, and 'fputs' doesn't?
Why does 'fgets' take a size argument, and 'gets' doesn't?
Why can i use the same format for float/double in 'fprintf', but not in
'fscanf'?
Why is it that multiply long and long gives long, but short and short
gives int?
Why can i use a bitfield in a struct, but not as a local variable?
Why is it that 'int' means signed, but 'char' can be either one?
Reply With Quote
  #25 (permalink)  
Old 02-20-2012, 09:46 PM
Keith Thompson
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

jgk@panix.com (Joe keane) writes:
> In article <lnboouef7m.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
>>strncpy *looks* like it should be to strcpy as strncat is to strcat,
>>but it isn't.

>
> Well there is a number of options.
>
> a) should it make sure there is a zero terminator
> b) maybe you want to clear everything that isn't copied
> c) does it handle overlapping copies
>
> Do i think it's slightly stupid that they don't match? A little bit.
> But one can imagine that good choices were made, and that consistency is
> sometimes negative.


The point is that strncpy is a very different function from strcpy.
It is not intended to work with a *string* in the target array;
it works with a specialized data structure (used to store file
names in very early Unix systems).

> Why does 'puts' add a newline, and 'fputs' doesn't?
> Why does 'fgets' take a size argument, and 'gets' doesn't?
> Why can i use the same format for float/double in 'fprintf', but not in
> 'fscanf'?
> Why is it that multiply long and long gives long, but short and short
> gives int?
> Why can i use a bitfield in a struct, but not as a local variable?
> Why is it that 'int' means signed, but 'char' can be either one?


There are answers for most of these questions. For others,
it's certainly true that the C standard library is not entirelyi
consistent. But I don't think any of them are particularly relevant
to strncpy.

I think you're understating the differences between strcpy and
strncpy. The strncpy function is radically different from strcpy,
and there are very few legitimate uses for it. On the other hand,
the deceptive name has led many C programmers to use it incorrectly,
and I strongly suspect that it's used incorrectly far more often
than it's used correctly.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply With Quote
  #26 (permalink)  
Old 02-20-2012, 09:51 PM
James Kuyper
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On 02/20/2012 04:25 PM, Joe keane wrote:
....
> Why can i use the same format for float/double in 'fprintf', but not in
> 'fscanf'?


Because float gets promoted to double when passed to fprintf(), while
the concept of "promoted type" doesn't even apply to the pointer
arguments passed to fscanf(). float* and double* are incompatible types,
which means they must be treated differently, and fscanf() needs to know
about that face.

> Why is it that multiply long and long gives long, but short and short
> gives int?


Integer types that are smaller than 'int' get promoted to 'int' on the
principle that 'int' should be the natural integer type for a given
platform. Integer types smaller than 'int' should be used only when
needed to save space - types larger than 'int' should be used only when
needed to represent large numbers.

....
> Why is it that 'int' means signed, but 'char' can be either one?


Because the normal character type on many of the machines that C was
first ported to was signed, while on many others it was unsigned,
whereas the normal integer type was (almost?) always signed.
--
James Kuyper
Reply With Quote
  #27 (permalink)  
Old 02-20-2012, 10:14 PM
Shao Miller
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On 2/19/2012 15:33, Keith Thompson wrote:
> jgk@panix.com (Joe keane) writes:
>> In article<lnvcn6fyi2.fsf@nuthaus.mib.org>,
>> Keith Thompson<kst-u@mib.org> wrote:
>>> There's rarely *any* reason to use strncpy(). It's not a "safer"
>>> version of strcpy(); it's a quite different function.

>>
>> It is a safer version of 'strcpy'. There is the issue of what to do if
>> the full copy can't be done, but that's program logic and the library
>> function can't read people's minds. Even if the program just calls
>> 'abort', that's a huge improvement.

>
> Did you not read my description of what strncpy actually does, or do you
> disagree with it?
>
> strncat is a "safer" version of strcat. It takes an extra argument
> "n" that specifies the maximum number of characters to be copied. If
> the source is longer than n characters, it appends just n characters.
> It properly zero-terminates the destination in all cases.
>
> strncpy *looks* like it should be to strcpy as strncat is to strcat,
> but it isn't. If the source string is shorter than n characters,
> it will pad the destination with multiple null characters, something
> that strcpy never does. If the source string is longer than n
> characters, it will leave the destination unterminated (i.e.,
> not a string).
>
> If it had been defined something like this:
>
> char *better_strncpy(char *dest, const char *src, size_t n) {
> dest[0] = '\0';
> return strncat(dest, src, n);
> }
>
> then it would be reasonable to call it a "safer" version of strcpy.
>
> (It's possible I have an off-by-one error in the above code;
> I haven't taken the time to check.)
>


My impression is that in:

char foo[] = "foo";
char bar[3] = "bar";
char baz[10] = "baz";

each of these could be roughly equivalent to:

char foo[sizeof "foo"];
char bar[3];
char baz[10];

strncat(foo, "foo", sizeof "foo");
strncat(bar, "bar", 3);
strncat(foo, "baz", 10);

And that in:

char blah[40] = { 0 };

this is roughly equivalent to:

char blah[40];

memset(blah, 0, 40);


And that in:

int blee[2][2] = { { 13, 42 } };

this is roughly equivalent to:

static const int hidden_blee_initializer[2][2] =
{ { 13, 42 }, { 0, 0 } };
int blee[2][2];

memcpy(blee, hidden_blee_initializer, sizeof blee);

Where each of these standard functions might be highly optimized and
where an implementation might actually choose to implement the
initializations using just the same logic.
Reply With Quote
  #28 (permalink)  
Old 02-20-2012, 11:09 PM
Rich Webb
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On Sun, 19 Feb 2012 12:33:01 -0800, Keith Thompson <kst-u@mib.org>
wrote:

>jgk@panix.com (Joe keane) writes:
>> In article <lnvcn6fyi2.fsf@nuthaus.mib.org>,
>> Keith Thompson <kst-u@mib.org> wrote:
>>>There's rarely *any* reason to use strncpy(). It's not a "safer"
>>>version of strcpy(); it's a quite different function.

>>
>> It is a safer version of 'strcpy'. There is the issue of what to do if
>> the full copy can't be done, but that's program logic and the library
>> function can't read people's minds. Even if the program just calls
>> 'abort', that's a huge improvement.

>
>Did you not read my description of what strncpy actually does, or do you
>disagree with it?
>
>strncat is a "safer" version of strcat. It takes an extra argument
>"n" that specifies the maximum number of characters to be copied. If
>the source is longer than n characters, it appends just n characters.
>It properly zero-terminates the destination in all cases.
>
>strncpy *looks* like it should be to strcpy as strncat is to strcat,
>but it isn't. If the source string is shorter than n characters,
>it will pad the destination with multiple null characters, something
>that strcpy never does. If the source string is longer than n
>characters, it will leave the destination unterminated (i.e.,
>not a string).
>
>If it had been defined something like this:
>
> char *better_strncpy(char *dest, const char *src, size_t n) {
> dest[0] = '\0';
> return strncat(dest, src, n);
> }
>
>then it would be reasonable to call it a "safer" version of strcpy.
>
>(It's possible I have an off-by-one error in the above code;
>I haven't taken the time to check.)


I'm surprised that the construct

strncpy(dest, source, BUF_LEN)[BUF_LEN - 1] = '\0';

hasn't been mentioned. It seems to be a reasonably compact way of
dealing with uncontrolled input.

--
Rich Webb Norfolk, VA
Reply With Quote
  #29 (permalink)  
Old 02-20-2012, 11:46 PM
Keith Thompson
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

Rich Webb <bbew.ar@mapson.nozirev.ten> writes:
[...]
> I'm surprised that the construct
>
> strncpy(dest, source, BUF_LEN)[BUF_LEN - 1] = '\0';
>
> hasn't been mentioned. It seems to be a reasonably compact way of
> dealing with uncontrolled input.


Yes, that should work. (I've never seen anyone actually use that
idiom; have you?)

Note that if dest is, say, 1000 bytes, and strlen(source)==3,
then it will write 997 null characters into dest, when 1 would do.
If the source string is from user or file input, that's probably
not going to be significant.

This avoids that problem:

dest[0] = '\0';
strncat(dest, source, BUF_LEN - 1);

Another problem is that it *silently* truncates overly long input.
(That might be just what you want.)

The problems of strncat can be worked around if you're aware of them,
but I'm skeptical that it's worth the effort.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply With Quote
  #30 (permalink)  
Old 02-20-2012, 11:46 PM
Shao Miller
Guest
 
Posts: n/a
Default Re: strncpy and 'n'

On 2/20/2012 19:09, Rich Webb wrote:
> On Sun, 19 Feb 2012 12:33:01 -0800, Keith Thompson<kst-u@mib.org>
> wrote:
>
>> jgk@panix.com (Joe keane) writes:
>>> In article<lnvcn6fyi2.fsf@nuthaus.mib.org>,
>>> Keith Thompson<kst-u@mib.org> wrote:
>>>> There's rarely *any* reason to use strncpy(). It's not a "safer"
>>>> version of strcpy(); it's a quite different function.
>>>
>>> It is a safer version of 'strcpy'. There is the issue of what to do if
>>> the full copy can't be done, but that's program logic and the library
>>> function can't read people's minds. Even if the program just calls
>>> 'abort', that's a huge improvement.

>>
>> Did you not read my description of what strncpy actually does, or do you
>> disagree with it?
>>
>> strncat is a "safer" version of strcat. It takes an extra argument
>> "n" that specifies the maximum number of characters to be copied. If
>> the source is longer than n characters, it appends just n characters.
>> It properly zero-terminates the destination in all cases.
>>
>> strncpy *looks* like it should be to strcpy as strncat is to strcat,
>> but it isn't. If the source string is shorter than n characters,
>> it will pad the destination with multiple null characters, something
>> that strcpy never does. If the source string is longer than n
>> characters, it will leave the destination unterminated (i.e.,
>> not a string).
>>
>> If it had been defined something like this:
>>
>> char *better_strncpy(char *dest, const char *src, size_t n) {
>> dest[0] = '\0';
>> return strncat(dest, src, n);
>> }
>>
>> then it would be reasonable to call it a "safer" version of strcpy.
>>
>> (It's possible I have an off-by-one error in the above code;
>> I haven't taken the time to check.)

>
> I'm surprised that the construct
>
> strncpy(dest, source, BUF_LEN)[BUF_LEN - 1] = '\0';
>
> hasn't been mentioned. It seems to be a reasonably compact way of
> dealing with uncontrolled input.
>


Or maybe:

strncpy(dest, source, BUF_LEN - 1)[BUF_LEN - 1] = '\0';
Reply With Quote
 
Reply

Thread Tools
Display Modes

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 Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 07:01 AM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.