Like Tree2Likes
  • 1 Post By Salem
  • 1 Post By nonoob

How?

This is a discussion on How? within the C Programming forums, part of the General Programming Boards category; Hello all, When I run this code: Code: #include <stdio.h> void main() { int k = 35 ; printf ( ...

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    27

    How?

    Hello all,

    When I run this code:
    Code:
    #include <stdio.h>
    
    void main()
    {
        int k = 35 ;
        printf ( "\n%d %d %d", k == 35, k = 50, k > 40 ) ;
    }
    The output is:
    Code:
    0 50 0
    I can't get how the compiler dealt with this...

    The only explanation is: The code is executed from right to left. So firstly, k is equal to 35. k > 40 is false. New value is assigned to k. k == 35 is false.

    Any help?
    Thanks in advance.

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Yep, that's as good an explaination as any.

  4. #4
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,788
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Understood... but that doesn't explain his results...

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by CommonTater View Post
    Understood... but that doesn't explain his results...
    Sure it does -- argument #2 is an assignment.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    It's the explanation. What he's observing is unspecified by standard.
    Evaluation may be from left to right also.

    In language like java, 'Argument Lists are always Evaluated Left-to-Right'. and you'll always get 1,50,1
    C does not grantee that.
    Last edited by Bayint Naung; 03-28-2011 at 07:31 AM.

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by MK27 View Post
    Sure it does -- argument #2 is an assignment.
    I think you misunderstood what I was saying...

    Simply telling hime that it's "unspecified" or "undefined" does not explain the results. The next compiler he tries that on may give different results... hense it is important to understand that it is undefined --compiler specific-- behavior. It does tell him why he shouldn't go that, but it doesn't explain the result...

    Noting that it's probably evaluating from right to left does offer something of an explaination.

    It's the difference between answering: "Don't do it" and "This may be why it happens".

  9. #9
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,831
    Yup. Looks like this compiler evaluated from right to left... same order as how the parameters are pushed to the stack. Makes sense. But as has been mentioned - order of evaluation is not specified in the standard. Other implementations may exist that go left-to-right, or any order.

    It sure would have been nice had the fine folks who wrote the standard included all of these type ambiguities and nailed them down. My guess is that they were forgetful and/or lazy, and that's why they were left out. Now it's officially "undefined" but it was never designed or meant to be a non-deterministic aspect of the compiler. Something like this evaluation order could have just as easily been specified since day1 and there would never be any more confusion. Now we're stuck with accepting undefined behaviour because, hey, the compiler writers "meant to do that". Ha!
    Last edited by nonoob; 03-28-2011 at 09:29 AM.

  10. #10
    Registered User
    Join Date
    Mar 2011
    Posts
    27
    Thanks guys for your responses. And thanks Bayint Naung and CommonTater.

  11. #11
    Registered User
    Join Date
    Mar 2010
    Posts
    531
    Quote Originally Posted by nonoob View Post
    Yup. Looks like this compiler evaluated from right to left... same order as how the parameters are pushed to the stack. Makes sense. But as has been mentioned - order of evaluation is not specified in the standard. Other implementations may exist that go left-to-right, or any order.
    Indeed. I just tried this out on the MSVC 2008 compiler -- it gave:

    Code:
    int k = 35 ;
    printf ( "\n%d %d %d", k == 35, k = 50, k > 40 ) ;
    output: 0 50 1
    Code:
    int k = 35 ;
    printf ( "\n%d %d %d", k == 35, k == 40, k = 40 ) ;
    output:  0 1 40
    So it did them in a different order each time (but both times did the assignment first). So... not only will any code that relies on this be non-portable, it might even break when only using one compiler.

    Quote Originally Posted by nonoob View Post
    It sure would have been nice had the fine folks who wrote the standard included all of these type ambiguities and nailed them down. My guess is that they were forgetful and/or lazy, and that's why they were left out. Now it's officially "undefined" but it was never designed or meant to be a non-deterministic aspect of the compiler. Something like this evaluation order could have just as easily been specified since day1 and there would never be any more confusion. Now we're stuck with accepting undefined behaviour because, hey, the compiler writers "meant to do that". Ha!
    Indeed. Made worse by the distinction between "unspecified" and "implementation defined". "Unspecified" seems to mean that it doesn't need to be documented per-implementation, as well as not being in the standard. If the compiler docs said "we do it this way" it wouldn't be so bad. Still would need some care in portable code, but at least you could be sure you knew what would happen, and that the compiler wouldn't change without warning.

    I hate unpredictable/undefined/unspecified/.... and I note that some compilers try to lock down and document unspecified behaviour (probably from customer demand). I wish all compilers would document what they do in 'unspecified' cases. Even if it's to document that it does something crazy and unreliable. Then you can decide whether or not you want to use said feature, instead of really not being able to.

  12. #12
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,831
    Thanks, smokeyangel, for your understanding. I expected people to immediately yell at me for bad mouthing the geniuses that are compiler writers and standards committee members. As if they're any smarter than many real programmers who write code for a living like many on this board. They ain't.

    It's hard to believe one compiler will do the evaluation in either order.

  13. #13
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,337
    The reason for all the unspecified and implementation defined behaviour is to give compiler writers a good deal of room to produce the best possible implementation.

    If you try to nail down too many rules, then not only would it be much harder to produce a validated compiler, it might have to do lots of unnecessary work on certain machines just to be compliant.

    When you've used a good number of compilers, you just forget about trying to write stupid over-optimised expressions (which never work anyway, except by pure dumb luck), and just write code which is within the standard.

    Occasionally, you make use of "implementation defined" behaviour, so long as you document it, and have RTM to make sure that is what you want.

    Undefined and unspecified behaviour is left to idiot tutors with nothing better to do than tease students with what does j++ + ++j do?
    To which the answer is, read this and stop asking such stupid questions!
    Comma Operator - C And C++ | Dream.In.Code
    Bayint Naung likes this.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  14. #14
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,831
    Heh. Good point about "tease students". Although I did find a discussion about sequence points fascinating. Funny how these things are irrelevant if you write reasonable, commercial-grade code for a living. And yet sadistic teachers and "clever" students find ways to create problems where there were none.
    Salem likes this.

Popular pages Recent additions subscribe to a feed

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