Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Debating With Friends

by exquisitemb (Novice)
on Mar 03, 2015 at 04:22 UTC ( [id://1118529]=perlquestion: print w/replies, xml ) Need Help??

exquisitemb has asked for the wisdom of the Perl Monks concerning the following question:

Hi All -- A friend is doing some weird embedded programming in C, and getting some strange results, so he asked what perl did (just for the sake of asking). I wrote up the quick comparison, and I got interesting results, now I'm intrigued. How/why does this work? (Yes, I know this is really stupid code)
#!/usr/bin/perl $x; if(($x=1) eq ($x=2)) { print "equal\n"; } else { print "not equal\n"; }
Result is that it gives is "equal". Why?

Replies are listed 'Best First'.
Re: Debating With Friends
by davido (Cardinal) on Mar 03, 2015 at 05:49 UTC

    In C or C++ this code invokes "undefined behavior" (behavior that is not defined by the C standard) because it relies on the order of evaluation of two sub-expressions that reside within the same sequence point. The == relational operator in C does not form a sequence point. But the = has a side effect. We cannot know (based on the C or C++ standards) what the order of evaluation will be when there is no sequence point defining the order. Therefore, we cannot know when the side effects will be applied. (See http://en.wikipedia.org/wiki/Sequence_point.)

    With C or C++, when the behavior is not defined by the standard, it is quite possibly different between various implementations, and in any implementation, could be surprising.

    Language lawyers in the C or C++ worlds love to shake their heads in condescending scorn when they see code that unknowingly invokes undefined behavior. Even with Perl, this is that sort of code; within the same sequence point, there is no formal definition of the order in which subexpressions will be evaluated. These subexpressions have side effects, and we cannot know when the side effects will take effect.

    With Perl we can reason about what probably will happen because the implementation is often accepted as the definition. But eq still doesn't form a sequence point, and in the absence of an explicit rule, I think this is one to avoid trusting in real code. It's still pretty much "undefined behavior".


    Dave

Re: Debating With Friends
by BrowserUk (Patriarch) on Mar 03, 2015 at 04:54 UTC
    Result is that it gives is "equal". Why?

    Because eq is a function with infix syntax. That is:  a eq b is actually eq( a, b ).

    Thus, by the time eq() sees the parameters, both assignments have been done, and it just gets two copies of the (same) final value.

    Viz

    sub eq{ print "@_"; $_[0] eq $_[1] };; print eq( $x=1, $x=2 );; Ambiguous call resolved as CORE::eq(), qualify as such or use & at (ev +al 13) line 1, <STDIN> line 5. Use of uninitialized value $_ in print at (eval 13) line 1, <STDIN> li +ne 5. print &eq( $x=1, $x=2 );; 2 2 1

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
Re: Debating With Friends
by GrandFather (Saint) on Mar 03, 2015 at 05:00 UTC

    Both assignments have to have been performed before the eq is evaluated so chances are eq is seeing the same value for $x. However there is no guarantee that that will be the case. The compiler could choose to cache the value from the left expression in which case the result would be false.

    As you hint, that is fundamentally broken code - in any context!

    Perl is the programming world's equivalent of English
Re: Debating With Friends
by Anonymous Monk on Mar 03, 2015 at 17:17 UTC
    The bottom line is this: such shortcuts benefit no one.
    use strict; use warnings; my $x = 1; my $y = 2; if($x == $y) { print "equal\n"; } else { print "not equal\n"; }
Re: Debating With Friends
by KurtSchwind (Chaplain) on Mar 09, 2015 at 12:57 UTC
    I see that the 'eq' operator has already been explained. I'll only add a link here which is really great for 'truthiness' in perl.
    True or False? A Quick Reference Guide
    --
    “For the Present is the point at which time touches eternity.” - CS Lewis

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1118529]
Approved by GrandFather
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (9)
As of 2024-03-28 09:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found