> On Tue, 21 Feb 2017, Steffen Nurpmeso wrote:
> ...
> > But mind you, it is true that i still think it is funny that this 
> > happened on a BSD system, the origin of bcopy(3).  To me memcpy(3) never 
> > has been anything but an optimization for cases where you know it is 
> > save, so that the tests, the move to the end to start there etc., can be 
> > avoided.  This was at least nine (9) cycles iirc on the above CPUs that 
> > can be saved, and that almost sufficient to copy a small string! Ciao.
> 
> The catch is that that the standard *doesn't* say "memcpy() copies the 
> buffer when they don't overlap or when the target is before the source". 
> It says "memcpy() copies the buffer if they don't overlap; the behavior is 
> not defined (i.e., *anything* can happen) if they overlap in any way".
> 
> Compilers now are saying "well, undefined behavior includes doing nothing 
> or acting like the arguments were totally different; I will assume that 
> this code path *cannot be reached* with arguments that have undefined 
> behavior".  For example, it would be a totally legal optimization for a 
> compiler to transform this:
>       memcpy(p, p+1, n);
> to
>       if (n)
>               p[0] = p[1];
> 
> The memcpy() behavior is only defined if there's no overlap, and overlap 
> occurs if n>1, ergo the behavior is only defined if n is zero or one.  
> Indeed, the compiler could then optimize the code *before* this memcpy() 
> call on the assumption that _that_ code could only leave n set to zero or 
> one!
> 
> 
> If your code triggers the memcpy() log+abort, then the code only works 
> elsewhere because the compiler isn't smart enough.  Yet.

How about undefined behaviour such as the following:

if (backwards) {
        fprintf(stderr, "                 ----------\n");
        fprintf(stderr, "                /          \\\n");
        fprintf(stderr, "               /    REST    \\\n");
        fprintf(stderr, "              /      IN      \\\n");
        fprintf(stderr, "             /     PEACE      \\\n");
        fprintf(stderr, "            /                  \\\n");
        fprintf(stderr, "            |     Steffen      |\n");
        fprintf(stderr, "            |       0 Au       |\n");
        fprintf(stderr, "            |   killed by a    |\n");
        fprintf(stderr, "            |    backward      |\n");
        fprintf(stderr, "            |      memcpy      |\n");
        fprintf(stderr, "            |       2017       |\n");
        fprintf(stderr, "           *|     *  *  *      | *\n");
        fprintf(stderr, "  _________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n");
        reboot(RB_NOSYNC);
        abort();
}

Reply via email to