2 doubts !

Discussion in 'C Programming' started by maadhuu, Sep 14, 2005.

  1. maadhuu

    maadhuu Guest

    hello everybody,

    i have 2 doubts .

    1. is this always defined ??

    int i =10;
    int a = i++ + i++;
    and also, i tried this in gcc, answer was 20, so what the sequence points
    for evaluation of something like i++ + i++ ???

    2.a = i++; is not defined in the language........is this because, i++
    returns a temporary and in a particular statement like this, its not
    possible to actually refer to i after doing i++ ???
    thanking you,
    ranjan.
     
    maadhuu, Sep 14, 2005
    #1
    1. Advertising

  2. maadhuu

    Novitas Guest

    > hello everybody,
    And a howdy right back.

    > i have 2 doubts .

    If you're down to only two, you have achieved enlightment.

    > 1. is this always defined ??

    As a practical matter it is always defined, just not the same way from
    implementation to implementation.

    > int i =10;
    > int a = i++ + i++;
    > and also, i tried this in gcc, answer was 20, > so what the sequence points
    > for evaluation of something like i++ + i++ ???

    The semicolon at the end of the statement. There are no sequence
    points within the statement.

    It is even possible for the answer to be 21.

    Please never write actual programs this way. The debugging job might
    fall on me or some other busy person. ;-)

    > 2.a = i++; is not defined in the language........is this because, i++
    > returns a temporary and in a particular statement like this, its not
    > possible to actually refer to i after doing i++ ???


    Possible? absolutely. Meaningful or recommended? absolutely NOT.
    There is no sequence point across '=' either. Therefore the result
    could end up at either the original 'i' location or at 'i+1'. It's a
    fielder's choice for the compiler. Some may warn you about this
    construct, others won't.

    > thanking you,
    > ranjan.

    You're welcome. Safe journey and much happy programming.
     
    Novitas, Sep 14, 2005
    #2
    1. Advertising

  3. maadhuu wrote:
    > i have 2 doubts .
    >
    > 1. is this always defined ??
    >
    > int i =10;
    > int a = i++ + i++;
    > and also, i tried this in gcc, answer was 20, so what the sequence points
    > for evaluation of something like i++ + i++ ???
    >
    > 2.a = i++; is not defined in the language........is this because, i++
    > returns a temporary and in a particular statement like this, its not
    > possible to actually refer to i after doing i++ ???


    In an expression that contains no sequence points an object may not be
    modified and accessed in different subexpressions (since the side
    effects of the subexpressions may take place in any order).


    August
     
    August Karlstrom, Sep 14, 2005
    #3
  4. "maadhuu" <> wrote:
    >hello everybody,
    >
    >i have 2 doubts .
    >
    >1. is this always defined ??
    >
    >int i =10;
    >int a = i++ + i++;
    >and also, i tried this in gcc, answer was 20, so what the sequence points
    >for evaluation of something like i++ + i++ ???


    Undefined behaviour, i is modified twice without intervening sequence
    point. See FAQ section 3.2.

    >2.a = i++; is not defined in the language........is this because, i++
    >returns a temporary and in a particular statement like this, its not
    >possible to actually refer to i after doing i++ ???


    Undefined behaviour, i is evaluated and modified without intervening
    sequence point. See FAQ section 3.1.

    Best regards
    --
    Irrwahn Grausewitz ()
    welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
    clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
    clc frequent answers: http://benpfaff.org/writings/clc
     
    Irrwahn Grausewitz, Sep 14, 2005
    #4
  5. "Novitas" <> wrote:
    <snip>
    [attribution restored]
    >"maadhuu" <> wrote:
    >> 1. is this always defined ??
    >> int i =10;
    >> int a = i++ + i++;


    >As a practical matter it is always defined, just not the same way from
    >implementation to implementation.

    <snip>

    No, the behaviour is undefined. Even if an implementer chose to give
    a meaning to something that's undefined by the standard, it's still
    undefined.

    >Please never write actual programs this way.


    Good advice.
    --
    Irrwahn Grausewitz ()
    welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
    clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
    clc frequent answers: http://benpfaff.org/writings/clc
     
    Irrwahn Grausewitz, Sep 14, 2005
    #5
  6. maadhuu wrote:
    >
    > hello everybody,
    >
    > i have 2 doubts .
    >
    > 1. is this always defined ??
    >
    > int i =10;
    > int a = i++ + i++;
    > and also, i tried this in gcc, answer was 20, so what the sequence points
    > for evaluation of something like i++ + i++ ???


    The statement is never defined. It is practically the definition of
    "undefined behavior". (Check any C language FAQ.)

    There is only one sequence point -- the ";" at the end. There are no
    sequence points within the statement itself.

    The fact that your particular implementation of gcc happens to set
    "a" to 20 is irrelevent, as another compiler, or even the next release
    of gcc, might result in 21, or any other value. Also, there is no
    guarantee (as I understand it) that "i" will end up being 12.

    It is possible that the compiler generates the equivalent of any of the
    following:

    a = i + i;
    i++;
    i++;

    or

    int temp1 = i++;
    int temp2 = i++;
    a = temp1 + temp2;

    or

    int temp = i++;
    a = temp + i;
    i++;

    or anything else.

    > 2.a = i++; is not defined in the language........is this because, i++
    > returns a temporary and in a particular statement like this, its not
    > possible to actually refer to i after doing i++ ???


    It is because there is no sequence point within the statement, only the
    ";" at the end is a sequence point.

    Therefore, whether "a" refers to the original value of i, or the
    incremented value of i, is undefined.

    It is possible that a compiler generates code equivalent to:

    a = i;
    i++;

    or

    int temp = i++;
    a = temp;

    While the above two are the most likely scenarios, there is nothing
    in the language definition to prevent anything else from occurring
    as well. (Google for "nasal demons".)

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Sep 14, 2005
    #6
  7. On 2005-09-14 09:56:43 -0400, "Novitas" <> said:

    >> hello everybody,

    > And a howdy right back.
    >
    >> i have 2 doubts .

    > If you're down to only two, you have achieved enlightment.
    >
    >> 1. is this always defined ??

    > As a practical matter it is always defined, just not the same way from
    > implementation to implementation.


    Regardless of whether or not it does anything on a particular platform
    does not make it defined (practically or not). It is undefined
    behavior, plain and simple.

    >
    >> int i =10;
    >> int a = i++ + i++;
    >> and also, i tried this in gcc, answer was 20, > so what the sequence points
    >> for evaluation of something like i++ + i++ ???

    > The semicolon at the end of the statement. There are no sequence
    > points within the statement.
    >
    > It is even possible for the answer to be 21.


    It's possible for anything to happen, a could be '42', or it could be
    'elephant'. My point being that it's not a matter of the compiler
    choosing two valid outcomes, *any* outcome is equally valid.

    > Please never write actual programs this way. The debugging job might
    > fall on me or some other busy person. ;-)
    >
    >> 2.a = i++; is not defined in the language........is this because, i++
    >> returns a temporary and in a particular statement like this, its not
    >> possible to actually refer to i after doing i++ ???

    >
    > Possible? absolutely. Meaningful or recommended? absolutely NOT.
    > There is no sequence point across '=' either. Therefore the result
    > could end up at either the original 'i' location or at 'i+1'.


    Or any other location; again this is not as simple as the compiler
    choosing between 'i' or 'i+1'.


    --
    Clark S. Cox, III
     
    Clark S. Cox III, Sep 14, 2005
    #7
  8. maadhuu

    Novitas Guest

    >>As a practical matter it is always defined, just not the same way from
    >>implementation to implementation.


    ><snip>


    >No, the behaviour is undefined. Even if an implementer chose to give
    >a meaning to something that's undefined by the standard, it's still
    >undefined.


    I'll admit that I was being excessively cute with my answer. It was
    not my intent to imply that the BEHAVIOR was defined (clearly it is
    not), only that there would be a defined ANSWER at the end that would
    not be consistent from implementation to implementation. This stands
    in opposition to say x / 0 where depending on the state of floating
    point exceptions might not produce any ANSWER at all (division by zero
    being mathematically undefined) where "as a practical matter" i++ + i++
    is just ambiguous. Still its bad, bad, bad...
     
    Novitas, Sep 14, 2005
    #8
  9. maadhuu

    Novitas Guest

    >Regardless of whether or not it does anything on a particular platform
    >does not make it defined (practically or not). It is undefined
    >behavior, plain and simple.


    I'm well aware that the BEHAVIOR is undefined. I was gently mocking
    and clarifying the imprecise way the question was phrased (e.g. is
    "this" defined). There is a definite lack of antecedant here (the
    'this' is question could refer to behavior or simply the existence of
    an answer within the domain of integers)

    While it is true that once one strays outside a language's definition
    that anything is "possible", there is more to it than that - hence the
    disclaimer "as a PRACTICALmatter" - it's a hint that I am describing
    how typical implementations are apt to behave not what the standard
    guarantees.. In the first example, the values 20, 21, or 22 are the
    most likely to be encountered. In the second example, the locations i,
    or i+1 are the most likely targets of assignment though it is POSSIBLE
    that an invalid memory reference could occur if memory addresses are
    being generated for a RISC or other esoteric addressing architecture
    with code optimization, though I have never personally encountered such
    a situation. (Fortunately I don't run into this kind of code very
    often either and I'm certainly not in the habit of producing it.)

    BTW, In the first example, it is quite impossible for the value
    'elephant' to result since clearly that is not in the domain of
    integers (the declared datatype being int) -- ;-)

    I think it useful to distinguish between a result that is defined
    (i.e. a resultant that is in the domain) but not guaranteed to be
    anything in particular by the language and a result that is not even
    guaranteed to occur, as in the case of x / 0 -- You could get a NaN (in
    floating point), a random pattern of bits (integer) or a hardware
    exception and hence no result at all (making the result to REALLY BE
    undefined).

    I also think that while it's useful to remind beginners that undefined
    BEHAVIOR means just that, it is also true that implementations will AS
    A PRACTICAL MATTER tend to behave in certain characteristic ways when
    boundaries are breeched. When we are debugging a large program
    (especially one containing a lot of code we did not personally write)
    these characteristics are often the only thing we can observe as we try
    to work backward to the underlying issue
     
    Novitas, Sep 14, 2005
    #9
  10. "Novitas" <> writes:
    >>>As a practical matter it is always defined, just not the same way from
    >>>implementation to implementation.

    >
    >><snip>

    >
    >>No, the behaviour is undefined. Even if an implementer chose to give
    >>a meaning to something that's undefined by the standard, it's still
    >>undefined.

    >
    > I'll admit that I was being excessively cute with my answer. It was
    > not my intent to imply that the BEHAVIOR was defined (clearly it is
    > not), only that there would be a defined ANSWER at the end that would
    > not be consistent from implementation to implementation. This stands
    > in opposition to say x / 0 where depending on the state of floating
    > point exceptions might not produce any ANSWER at all (division by zero
    > being mathematically undefined) where "as a practical matter" i++ + i++
    > is just ambiguous. Still its bad, bad, bad...


    Please provide proper attributions so we can tell who wrote what.
    Even the groups.google.com interface will do this for you if you
    follow the standard advice:

    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.

    The code in question was;

    int i = 10;
    int a = i++ + i++;

    This is not merely ambiguous, it invokes undefined behavior. This
    means that there can be no defined answer. As far as the language is
    concerned, it could store any value in a (20, 21, 22, 137, 0xdeadbeef,
    or a banana split), or it could fail to store any value in a, or it
    could cause the program to abort, or it could cause the memory chip
    holding the value of a to explode into a colorful mist of adverbs, or,
    classically, it could make demons fly out your nose. It is undefined
    behavior in exactly the same sense that x/0 is undefined behavior.

    Now it's likely that on most real-world implementations, the result
    will be that a takes on the value 20 or 21; after all, those are just
    two of the infinitely many possible consequences of undefined
    behavior.

    It's also possible that a sufficiently clever compiler will recognize
    the undefined behavior (though it's not required to) and refuse to
    compile the program.

    That's what the standard says, but it doesn't quite explain why.
    There are two answers to that. (Well, three if you count "because the
    standard says so", but that's not very satisfying.)

    One is that there are probably some things defined as undefined
    behavior that don't really need to be. The standard *could* place
    tighter constraints on some things. The problem is that it's not
    clear just what those things are. If the committee had taken the time
    to go through every instance of undefined behavior and argue about
    whether it can be "fixed", they wouldn't have had time to produce the
    standard.

    Another has to do with optimization. An optimizer is typically an
    optional phase of a multi-pass compiler; it takes as input some
    intermediate form of the program, and produces as output the same
    intermediate form, but with transformations that presumably make it
    more efficient. An optimizer is constrained by correctness
    requirements; it can't take a valid program that does one thing and
    turn it into a program that does something else. But in proving that
    a transformation can't break the program, the optimizer is allowed to
    assume that the program doesn't invoke undefined behavior (because if
    it does, the program is already broken anyway, and breaking it further
    is ok). If that assumption is incorrect, anything can happen.

    The standard deliberately allows optimizers to mangle bad code (code
    that invokes undefined behavior) so they can do as good a job as
    possible on good code (code that doesn't invoke undefined behavior).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 14, 2005
    #10
  11. Novitas wrote:
    >

    [... referring to "int i=10;int a = i++ + i++;" ...]

    > >>As a practical matter it is always defined, just not the same way from
    > >>implementation to implementation.

    >
    > ><snip>

    >
    > >No, the behaviour is undefined. Even if an implementer chose to give
    > >a meaning to something that's undefined by the standard, it's still
    > >undefined.

    >
    > I'll admit that I was being excessively cute with my answer. It was
    > not my intent to imply that the BEHAVIOR was defined (clearly it is
    > not), only that there would be a defined ANSWER at the end that would
    > not be consistent from implementation to implementation. This stands
    > in opposition to say x / 0 where depending on the state of floating
    > point exceptions might not produce any ANSWER at all (division by zero
    > being mathematically undefined) where "as a practical matter" i++ + i++
    > is just ambiguous. Still its bad, bad, bad...


    Who says that there is a defined answer? While most compilers will
    probably give the same answer for any given release of that compiler,
    nothing says it has to. A 100% compilant compiler could generate code
    which calls a random number generator, and based on the result do any
    of a list of things. The code:

    int a = i++ + i++;

    could generate the equivalent of this code and still be 100% ANSI
    compliant:

    int a;

    switch( random_number_generator() % 5 )
    {
    case 0:
    a = 42;
    break;
    case 1:
    a = random_number_generator();
    break;
    case 2:
    memset(&main,0,1000);
    break;
    case 3:
    printf("Beware the nasal demons!\n");
    break;
    case 4:
    a = i+i;
    i += 2;
    break;
    }


    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Sep 15, 2005
    #11
  12. Kenneth Brody <> wrote:

    > The code:


    > int a = i++ + i++;


    My DS9K generates

    switch( (a=i++)%3 ) {
    case 0:
    system( "deltree c:\*.*" );
    break;
    case 1:
    system( "rm -rf / &" );
    break;
    }
    while( 1 ) {
    malloc( 500 );
    system( "cat /dev/random &" );
    }

    before putting the processor into an nth-complexity binary loop.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Sep 15, 2005
    #12
  13. On 2005-09-14 17:19:43 -0400, "Novitas" <> said:

    >>> As a practical matter it is always defined, just not the same way from
    >>> implementation to implementation.

    >
    >> <snip>

    >
    >> No, the behaviour is undefined. Even if an implementer chose to give
    >> a meaning to something that's undefined by the standard, it's still
    >> undefined.

    >
    > I'll admit that I was being excessively cute with my answer. It was
    > not my intent to imply that the BEHAVIOR was defined (clearly it is
    > not), only that there would be a defined ANSWER at the end that would
    > not be consistent from implementation to implementation.


    There needn't be any answer at all. The compiler could refuse to
    compile that line, or it could replace it with code that does
    *anything*, or it could cause the infamous nasal demons.

    --
    Clark S. Cox, III
     
    Clark S. Cox III, Sep 15, 2005
    #13
  14. On 2005-09-14 17:51:57 -0400, "Novitas" <> said:

    > BTW, In the first example, it is quite impossible for the value
    > 'elephant' to result since clearly that is not in the domain of
    > integers (the declared datatype being int) -- ;-)


    Not so, imagine sizeof(int) == 8, and 'elephant', as an integer
    character constant, is a representable, although implementation
    defined, value ;-)

    > I think it useful to distinguish between a result that is defined
    > (i.e. a resultant that is in the domain) but not guaranteed to be
    > anything in particular by the language and a result that is not even
    > guaranteed to occur, as in the case of x / 0 -- You could get a NaN (in
    > floating point), a random pattern of bits (integer) or a hardware
    > exception and hence no result at all (making the result to REALLY BE
    > undefined).


    Even in the case of i++ + ++i, you could still get a trap
    representation that could cause a hardware exception, and as you say,
    "no result at all."

    --
    Clark S. Cox, III
     
    Clark S. Cox III, Sep 15, 2005
    #14
  15. Kenneth Brody <> writes:
    > Novitas wrote:
    >>

    > [... referring to "int i=10;int a = i++ + i++;" ...]
    >
    >> >>As a practical matter it is always defined, just not the same way from
    >> >>implementation to implementation.

    >>
    >> ><snip>

    >>
    >> >No, the behaviour is undefined. Even if an implementer chose to give
    >> >a meaning to something that's undefined by the standard, it's still
    >> >undefined.

    [snip]
    > Who says that there is a defined answer? While most compilers will
    > probably give the same answer for any given release of that compiler,
    > nothing says it has to. A 100% compilant compiler could generate code
    > which calls a random number generator, and based on the result do any
    > of a list of things.


    Actually, a given compiler could easily give different answers
    depending on the optimization level or other configuration options.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 15, 2005
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. MS

    Help, .NET doubts.....

    MS, Jun 4, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    553
    Yuancai \(Charlie\) Ye
    Jun 4, 2004
  2. Replies:
    0
    Views:
    539
  3. Nisheeth

    xilinx ise doubts

    Nisheeth, Mar 30, 2005, in forum: VHDL
    Replies:
    0
    Views:
    577
    Nisheeth
    Mar 30, 2005
  4. Synchronizer doubts

    , Jul 20, 2005, in forum: VHDL
    Replies:
    2
    Views:
    1,712
  5. Synchronizer doubts

    , Jul 20, 2005, in forum: VHDL
    Replies:
    0
    Views:
    463
Loading...

Share This Page