This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Implement C11 annex K?


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]