Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20150728125710.E027Y.34626.imail@eastrmwml107>
Date: Tue, 28 Jul 2015 12:57:10 -0400
From:  <jfoug@....net>
To: john-dev@...ts.openwall.com
Subject: Re: Ambiguous pointer increments

---- Lukas Odzioba <lukas.odzioba@...il.com> wrote: 
> 2015-07-27 23:46 GMT+02:00 Mateusz Tabaka <tabsysdebug@...il.com>:
> > The '||' operator guarantees left-to-right evaluation (6.5.14.4).
> 
> I don't see logical OR operator here, I see bitwise OR.

precedence rules do not matter, it could have been a +, * or even grouped with ().  Also, pre-increment or post increment do not matter either.

The code modifies a variable twice between defined sequence points. You can not do that, it is strictly forbidden.  That it happened to work on some systems was simply do to how certain things were implemented within those compilers.

Ok, lets look at this undefined example:   val = (*p++) | ( (*p++) <<8);

this could end up being any of these (and probably others) depending upon the compiler, AND it may even be handled differently depending upon compiler optimizations.
   val = *p; p += 2;
   val = *p; p += 1;
   val = *p;
   val = *p|(p[1]<<8); p+=2;
   val = *p|(p[1]<<8);

This shows WHY this is considered to be undefined. It certainly is 'forbidden' code, but it does not mean people will not use it.  MOST compilers are not smart enough (even though they 'could') to detect this sort of undefined behavior.

Again, the 'classic' undefined example is x=x++;    If compilers warned about this, then this code should scream warnings (it does with -Wall)

#include <stdio.h>
int main() {
   int x=0;
   x = x++;
   printf("%d ", x);
   x = ++x;
   printf("%d\n", x);
   return 0;
}

$ gcc -O2  undef.c

Buf if I do a -Wall (or just -Wsequence-point) on my gcc, I get this:

$ gcc -O2 -Wsequence-point undef.c
ab.c: In function ‘main’:
ab.c:4:6: warning: operation on ‘x’ may be undefined [-Wsequence-point]
    x = x++;
      ^
ab.c:6:6: warning: operation on ‘x’ may be undefined [-Wsequence-point]
    x = ++x;
      ^

What is happening is x is being modified 2 times on each of this expressions.  one is the assignment, and the other is the increment.  The output of the program might be "0 1"  it might be "1 2" it might be "1 3"  My gcc always outputs "0 1", but that does not mean "0 1" is the 'right' answer. The answer is not defined to be anything.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.