Like Tree8Likes
  • 1 Post By anduril462
  • 1 Post By laserlight
  • 6 Post By grumpy

undefined behaviour

This is a discussion on undefined behaviour within the C Programming forums, part of the General Programming Boards category; In the book called gnu c manual I read that the following code has an undefined behavior i=++i +1; Because ...

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    50

    undefined behaviour

    In the book called gnu c manual I read that the following code has an undefined behavior
    i=++i +1; Because since the variable i is modified more than once between the sequence point,it is not sure that what value will 'i' have..But it is evident that the final value in 'i'(if i=1) would be 3..Can someone please clear my doubt..

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,444
    Check out these links: Expressions and in particular Question 3.10a.

    That whole site is worth reading over from time to time, and it's a great one to keep handy as a reference too.
    Saurabh Mehta likes this.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,430
    Quote Originally Posted by Saurabh Mehta
    But it is evident that the final value in 'i'(if i=1) would be 3..Can someone please clear my doubt..
    The standard says that such expressions result in undefined behaviour, so they result in undefined behaviour and must be avoided, even if you think that the behaviour will give the same result no matter what. The point is that the compiler is not required to follow your reasoning: there might be some kind of optimisation for which the result would be say, 2.
    Saurabh Mehta likes this.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,205
    Quote Originally Posted by Saurabh Mehta View Post
    .But it is evident that the final value in 'i'(if i=1) would be 3..Can someone please clear my doubt..
    It may be evident to you, but the standard (by allowing the behaviour to be undefined) does not mandate anything about how a compiler will interpret that code.

    Let's look at the case
    Code:
        i = ++j + 1;
    (where j is not an alias for i), and j initially has a value of 1.

    One interpretation of this is that
    1) Value of 1 is stored in register A.
    2) Value of j is fetched into register B.
    3) Register B is incremented.
    4) Value in Register B is added to value in Register A.
    5) Value in register A is copied to variable i.
    6) Value in Register B is copied to variable j.

    This is not the only way it might be done, but this sequence of events is guaranteed to give the required results. The end result is that j has been incremented, and i has a value equal to the original j plus 2.

    Now, let's say the compiler does the same thing, except that j is an alias for i. (All I've done in the sequence below is take the sequence above, and substitute i where it referred to j).
    1) Value of 1 is stored in register A.
    2) Value of i is fetched into register B.
    3) Register B is incremented.
    4) Value in Register B is added to value in Register A.
    5) Value in register A is copied to variable i.
    6) Value in Register B is copied to variable i.

    (Notice that Step 6 cancels out the effect of Step 5). The end result, if i initially has the value of 1, is that i will have the value of 2.

    Now you could argue that the compiler should detect that i and j are aliased, and emit different code. That is not always possible. For example, if in one source file
    Code:
    void stuff(int *x, int *y)
    {
         *x = ++(*y) + 1;
    }
    and in another
    Code:
    #include <stdio.h>
    void stuff(int *, int *);
    
    int main()
    {
         int i = 1;
         stuff(&i, &i);
         printf("%d\n", i);
    }
    the compiler has no way of knowing that x and y point to the same int. Yes, you can detect it. But a compiler is not required to do such error checking for you.
    Right 98% of the time, and don't care about the other 3%.

  5. #5
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,831
    i=++i +1 does not constitute a multiple sequence point issue. The expression on the right of the assignment is evaluated without any conflicts. The variable is not referenced and updated more than once. Then the assignment is made (lowest precedence in this case) - which happens to involve a variable that's long since been accessed and forgotten. The post-increment implicit assignment is simply overridden.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,430
    Quote Originally Posted by nonoob
    i=++i +1 does not constitute a multiple sequence point issue. The expression on the right of the assignment is evaluated without any conflicts. The variable is not referenced and updated more than once. Then the assignment is made (lowest precedence in this case) - which happens to involve a variable that's long since been accessed and forgotten. The post-increment implicit assignment is simply overridden.
    The full rule, according to C99, is:
    Quote Originally Posted by C99 Clause 6.5 Paragraph 2
    Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
    There is a corresponding note:
    Quote Originally Posted by C99 Clause 6.5 Note 70
    This paragraph renders undefined statement expressions such as
    Code:
    i = ++i + 1;
    a[i++] = i;
    while allowing
    Code:
    i = i + 1;
    a[i] = i;
    Hence, contrary to your claim, i=++i+1 does constitute an issue with modifying a value more than once between consecutive sequence points. What you may have missed is that the assignment operator does not introduce a sequence point.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,831
    I stand corrected. According to Wiki ( Sequence point - Wikipedia, the free encyclopedia )
    An often-cited example is the C expression i=i++, which apparently both assigns i its previous value and increments i. The final value of i is ambiguous, because, depending on the order of expression evaluation, the increment may occur before, after, or interleaved with the assignment.

    I thought surely an assignment is a sequence point. Especially since it has a low precedence it should be executed last. I realize operator precedence does not dictate execution order in theory.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,205
    Quote Originally Posted by nonoob View Post
    I thought surely an assignment is a sequence point.
    You thought wrong.

    Quote Originally Posted by nonoob View Post
    Especially since it has a low precedence it should be executed last.
    It does. But that has nothing to do with how many times particular variables have their values fetched, or have their values modified. That is why the standard specifies a limit on such things (i.e. once per expression), as per the text that laserlight quoted.

    In the expression "i = ++i + 1", two of the operators (pre-increment and assignment) each work by modifying their operand (which is i in both cases). That means the expression requires two modifications of i, which runs afoul of the upper limit that i can only be modified once. Hence the expression yields undefined behaviour.
    Right 98% of the time, and don't care about the other 3%.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,430
    Quote Originally Posted by nonoob
    Especially since it has a low precedence it should be executed last.
    Quote Originally Posted by grumpy
    It does.
    [/quote]
    I would hasten to add that "it does" in this case because there is no alternative order of evaluation in which the assignment, due to the low precedence, cannot be evaluated last. In general, precedence is concerned with grouping, not order of evaluation.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. undefined behaviour.
    By juice in forum C Programming
    Replies: 3
    Last Post: 12-21-2011, 12:03 PM
  2. Undefined behaviour telnet
    By stevesmithx in forum Tech Board
    Replies: 0
    Last Post: 04-22-2008, 01:41 AM
  3. bit shifting...undefined behaviour?
    By Sebastiani in forum C++ Programming
    Replies: 15
    Last Post: 11-07-2007, 01:11 PM
  4. Is this undefined behaviour?
    By caduardo21 in forum C Programming
    Replies: 4
    Last Post: 01-15-2006, 11:55 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21