News for hackers. Stuff that matters.
Re:Conflating pointers with arrays: C's biggest mistake? (2009) by WalterBright on Sunday July 22, 2018 @04:27AM (#17585839)
strcpy(s1,s2) does a strlen on s2.

strcat(s1,s2) does a strlen on s1 and s2.

Now, two of the strlen's can be replaced with byte-by-byte copies checking for 0 for each, but that tends to lose the efficiency that a memcpy would bring, so you're pretty much suffering from it anyway.

BTW, here's the strcat I wrote eons ago:

https://github.com/DigitalMars/dmc/blob/master/src/CORE32/ST...

It does do two strlen's (the repne scasb instructions). With the improvements in CPUs since there are probably better ways to write it, but that was pretty good for its day.

Here's strcpy:

https://github.com/DigitalMars/dmc/blob/master/src/CORE32/ST...

which does the test-every-byte method. I think Steve Russell wrote it, but I'm not sure.

If there's anything efficiently implemented in a C compiler, it's memcpy. Being able to implement string processing in terms of memcpy leverages that very nicely. strcat() and strcpy() don't leverage it.

Which do you think is faster (s2 is 1024 bytes long)?

    strcpy(s1, s2);
    memcpy(s1, s2, 1024);
I've dramatically speeded up a lot of my code and other peoples' by replacing the strxxx functions with memcpy. It's low hanging fruit and one of the first things I look for.
Re:Conflating pointers with arrays: C's biggest mistake? (2009) by WalterBright on Sunday July 22, 2018 @04:49AM (#17585891)
To illustrate the advantage of memcpy, consider this inner loop possible implementation:

    mov EAX,[ESI]
    mov EBX,4[ESI]
    mov ECX,8[ESI]
    mov EDX,12[ESI]
    mov [EDI],EAX
    mov 4[EDI],EBX
    mov 8[EDI],ECX
    mov 12[EDI],EDX
    add ESI,16
    add EDI,16
Modern processors can likely do the 4 loads and 4 stores in parallel. That can't be done with 0 terminated strings, as you have to check every byte for 0. Even worse, you have to take care not to seg fault by reading too far past the 0, as there may not be any valid memory there.
Re:Conflating pointers with arrays: C's biggest mistake? (2009) by gpderetta on Sunday July 22, 2018 @08:45AM (#17586455)
Well, you can use vevctorized string operations that allow for null terminated strings.

I do agree with the general idea that null terminated strings are a mistake though.

Re:Conflating pointers with arrays: C's biggest mistake? (2009) by shakna on Sunday July 22, 2018 @04:42AM (#17585876)
I'm usually one to lean on your knowledge, but looking at glibc's strcpy [0], I don't see a strlen. I do see two macros, CHECK_BOUNDS_LOW and CHECK_BOUNDS_HIGH, which get defined about here [1].

Am I missing something?

[0] https://github.com/lattera/glibc/blob/master/string/strcpy.c

[1] https://github.com/lattera/glibc/blob/master/sysdeps/generic...

Re:Conflating pointers with arrays: C's biggest mistake? (2009) by WalterBright on Sunday July 22, 2018 @04:52AM (#17585896)
Good question. I preface this by the fact that I am not any expert on gcc compiler internals, I am assuming how I'd do it.

1. This implementation tests every byte, as discussed in other posts here. That makes it slow.

2. This implementation is likely not used - the gcc compiler probably has an internal code sequence it emits for a strcpy.

Re:Conflating pointers with arrays: C's biggest mistake? (2009) by MikeWey on Sunday July 22, 2018 @05:46AM (#17586024)
Seeing that the implementation relies on CHECK_BOUND_(HIGH/LOW) it's using bounded pointers, which are implemented as structs holding 3 fields. The value, the upper bound and the lower bound. That's one extra field compared to D arrays.

The function still checks every byte for \0.

And if i'm reading it correctly, only checks the upper bound after copying the data. And checking it before copying would require a call to strlen.

Re:Conflating pointers with arrays: C's biggest mistake? (2009) by iforgotpassword on Sunday July 22, 2018 @05:05AM (#17585932)
I would've assumed glibc has a bunch of different implementations and then picks the fastest one at runtime depending on CPU capabilities, but maybe they just scrapped that since GCC has built-in versions of most string functions anyways, since it can often know or at least guess the characteristics of the input and output (length, alignment) and emit different code depending on that.