This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Implement C11 annex K?
- From: Russ Allbery <eagle at eyrie dot org>
- To: libc-alpha at sourceware dot org
- Date: Wed, 13 Aug 2014 22:25:18 -0700
- Subject: Re: Implement C11 annex K?
- Authentication-results: sourceware.org; auth=none
- References: <E1XHe8v-0004Ur-Hp at rmm6prod02 dot runbox dot com> <Pine dot LNX dot 4 dot 64 dot 1408132054090 dot 16622 at digraph dot polyomino dot org dot uk> <53EBD7D9 dot 1040008 at cs dot ucla dot edu> <20140813213520 dot GQ12888 at brightrain dot aerifal dot cx> <53EBEACD dot 3070000 at googlemail dot com> <87k36cc559 dot fsf at windlord dot stanford dot edu> <20140814022501 dot GT12888 at brightrain dot aerifal dot cx>
Rich Felker <dalias@libc.org> writes:
> On Wed, Aug 13, 2014 at 04:59:46PM -0700, Russ Allbery wrote:
>> If the answer is "use strcpy and strcat because this code is provably
>> correct with them," I guess I understand your position, but if I
>> somehow
> The answer is "use memcpy".
memcpy would make that code harder to read and understand, or at least it
did when I tried to write it that way. Instead of:
for (i = 1; i < vector->count; i++) {
strlcat(string, seperator, size);
strlcat(string, vector->strings[i], size);
}
you get code more like:
for (i = 1; i < vector->count; i++) {
complen = strlen(vector->strings[i]);
assert(size - offset >= seplen + complen);
memcpy(string + offset, separator, seplen);
offset += seplen;
memcpy(string + offset, vector->strings[i], complen);
offset += complen;
}
string[offset] = '\0';
which I, at least, find harder to read and harder to be sure is correct.
(Admittedly, the error checking is arguably better since this asserts if
the string size calculation was wrong, but you can change the strlcat
version to do that as well if you want without much change.) I'm not
seeing any advantages over strlcpy and strlcat except for performance,
which doesn't matter here. So this is my dubious face, although maybe I'm
missing some good way to express this algorithm using memcpy that isn't
painful to read and doesn't require checking even more pointer math.
In general, I try to write C code that does not do lots of pointer math,
since I've found that most memory overrun bugs in my own code happen
because of pointer math that I got wrong.
So far, I'm afraid y'all are reinforcing my opinion that strlcat and
strlcpy are a fairly good API for writing code that constructs strings
dynamically from a number of elements known only at runtime. asprintf is
far better in places where it can be used easily (and I use it by
preference), but that sort of string construction is not one of them.
Well, at least unless you're willing to keep allocating more memory for
each part of the string assembly and recopying the data, and while
performance doesn't matter for this, I'm not sure that extends to doing a
malloc and free for each addition of another component to the string.
--
Russ Allbery (eagle@eyrie.org) <http://www.eyrie.org/~eagle/>