Re: Bug/Gross InEfficiency in HeathField's fgetline program



"Keith Thompson" <kst-u@xxxxxxx> a écrit dans le message de news:
lnd4unt6i8.fsf@xxxxxxxxxxxxxxxxxx
Richard <rgrdev@xxxxxxxxx> writes:
James Kuyper <jameskuyper@xxxxxxxxxxx> writes:
[...]
There are other plausible ways of defining what is meant by a "string
copy function", but requiring that it always copy the entire string,
including the terminating null character, and write nothing more than
the string, seems like a reasonable requirement to me.

Yes it is reasonable. As is

,----
| The strncpy() function is similar, except that at most n bytes of src
| are copied. Warning: If there is no null byte among the first n
| bytes of src, the string placed in dest will not be null
| terminated.
`----

The "string placed in dest" is the clue.

It's a clue that the person who wrote that description of strncpy()
got it wrong. A "string" in C is null terminated by definition; if
it's not null terminated; it's not a string. C99 7.1.1p1: "A string
is a contiguous sequence of characters terminated by and including the
first null character."

The portion you quoted also doesn't say that null characters are
appended if the source array is a string shorter than n characters;
perhaps you just didn't include that part.

The existence of documentation that incorrectly describes the
strncpy() function doesn't prove that it's a "string function". Out
of curiosity, where did you get that description? If it's from a
current system, you might consider submitting a bug report.

The linux man page for strncpy contains that language. Shame on them.

You see what makes it so childishly simple is the "n" bit in the
name. it doesn't take a genius to figure out that n means
something. Possibly the number of characters to copy? Surely not!
[...]

If I didn't know about the strncpy() function, and didn't have access
to the documentation, I'd probably assume that it's a safer version of
strcpy() that lets you specify the size of the target array. A call
like
strncpy(dest, source, n);
would (hypothetically) behave like strcpy(dest, source), except that
it wouldn't copy more than n characters in the dest array. If
strlen(source)+1 <= n, it would behave just like strcpy(dest, source).
Otherwise, it would copy the first n-1 characters of source into dest,
and set dest[n-1] to '\0'. It would not copy additional '\0'
characters into the dest array. In any case, as long as source points
to a valid string and dest points to an array of at least n
characters, dest would point to a valid string after the call.

That's exactly what BSD's strlcpy does, and I agree with you that it's what
an unsuspecting programmer would expect.

In other words, this:
strncpy(dest, source, n);
would be equivalent to this:
dest[0] = '\0';
strncat(dest, source, n);

NO! strncat is misleading too, but in a different way: it copies no more
than n characters to the end of dest, and appends a '\0' terminator. Thus
strlcpy(dest, source, n) would be equivalent to

if (n > 0) {
dest[0] = '\0';
strncat(dest, source, n - 1);
}

There are several other functions with an added 'n' in their names
that behave in this manner: strncat, snprinf, vsnprintf.

Not strncat. But [v]snprintf do, as well as other functions in the C
library: fgets (with size passed as an int for obscure reasons), and some
that do not truncate the destination: strftime, [v]swprintf, wcsxfrm,
wcsftime...

The behavior of strncpy() is *not obvious*. I completely agree that
programmers should not attempt to use it (or any other function)
without understanding how it works (though a beginning programmer
doesn't need to understand the details of format strings to write
``printf("hello, world\n");''). I don't mind having strncpy() in the
standard library, but I wish it had a different name, and I wish that
there were a strncpy() function that behaves as I've described above.
But it's far too late to make such a change.

I agree, except that I do mind that strncpy be in the Standard library, and
I don't think it is too late to try and deprecate it of at least discourage
its use.

Some questions:

What *exactly* do you mean by the phrase "string function"?

Pretty much yours.

Does strncpy() meet your definition?

Not really: it fits my definition of broken, ill-fated, useless,
to-be-deprecated function.

Do you use strncpy() in your own code?

I most certainly don't ! I have a #define in our in house include files to
prevent any use of this function a few other ones such as gets.

--
Chqrlie.


.



Relevant Pages

  • Re: Char pointer - How to give value?
    ... characters into sbuff. ... Since it has "str" in its name and modifies a string ... char* to also be a string. ... I have never found a use for strncpy(). ...
    (comp.lang.c)
  • Re: Bug/Gross InEfficiency in HeathFields fgetline program
    ... including the terminating null character, ... the string, seems like a reasonable requirement to me. ... It's a clue that the person who wrote that description of strncpy() ... The portion you quoted also doesn't say that null characters are ...
    (comp.lang.c)
  • Re: Prothon should not borrow Python strings!
    ... """It does not make sense to have a string without knowing what encoding ... same cul de sac as Python. ... Prothon_String_As_ASCII // raises error if there are high characters ... Python's split between byte strings and Unicode strings is ...
    (comp.lang.python)
  • Re: Letter to US Sen. Byron Dorgan re unpaid overtime
    ... put them in stupid places. ... Programming is difficult (as you must surely appreciate, ... > strings will be in the range 1...1000 characters. ... impose an artificially small limit on string length." ...
    (comp.programming)
  • Re: supplementary C frequent answers
    ... > "Using strncpy() into a large buffer can be very ... > time if the destination buffer is much longer than ... string that is shorter than n characters, ...
    (comp.lang.c)