Strcpy(). didn't know this until now

I was porting some extremely ancient software that had its origin on QNX 1.0 to Linux. I notice a weird bug that did not show up on QNX. After some debugging it turned out to have to do with strcpy being used on an overlapping buffer.

char buffer[##]

strcpy(buffer, buffer+1)

I would expect this to move the data in a buffer over one. That’s exactly what it does on QNX. The results on Linux were at the very least strange. It would copy some of the bytes and then quit.

The reason for the problem is that on Linux and Unix, using strcpy() on an overlapping buffer is undefined. I can see where copying the other way strcpy(buffer+1, buffer) might give strange results or even cause a crash. I believe there’s some code in K&R’s first edition that looks something like this:

char *strcpy(char *dest, char *src)
{
char *org_dest;

org_dest = dest;

while(*src)
*dest++ = *src++
*dest = 0;

return(org_dest);

}

This code does the copy without a problem.

QNX strcpy() documentation (I checked 6.5-SP1, 6.6.0, 7.0.0, 7.1.0) say :

It does work at least up to 6.5. That’s 1.0 → 6.5. I’ll be checking 7.1 shortly. What I find strange is that it would work differently from Linux since in both cases I’m using gcc.

I should note, the code also worked properly on Linux with g++.

The documentation says it is not guaranteed to work properly.
It does not say it is guaranteed to not work properly.
Subtle difference :wink:

I googled around on this and it appears that the problem has to do with 4 byte boundaries (8 bytes in 64 bit land) that most modern compilers are now using since RAM is so cheap.

https://demin.ws/blog/english/2011/07/14/strcpy-on-overlapped-strings/

I wonder if your Linux code would work if you used a Pragma pack(push, 1) and Pragma pack(pop) so that your string was 1 byte boundaries.

Tim

The stackoverflow.com you listed shows the problem exactly as I found it. The prama pack(push, 1) is and interesting idea. I solved the problem easily by substituting the code I listed above. Clearly the people in control of the code decided in favor of speed instead of functionality. Well at least in the Linux/Unix world. As I mentioned, the code works as expected in QNX 1.0 through 6.5. I haven’t tested beyond this but I will have to. Actually that is QNX .43 through 6.5, but that’s another story.

When you tested QNX 6.0-6.5, were you using GCC 2.95 (the default compiler) which is really old or the newer one you have to specify (3.3.1)?

The newer ones (including 4.4.2) may very well exhibit the same issues as Linux.

Tim

I haven’t paid any attention to the version I was using. The software I’m compiling has run on every version of QNX up to 6.5 so was undoubtedly compiled on every version of compilers that QNX has ever supported. I’m going to check whether the problem exists on the newer version. If you want any more details, we should take it off line. My email is maschoen@gmail.com.