Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

No warning when assiging to a variable

by mikeraz (Friar)
on Aug 14, 2013 at 18:39 UTC ( #1049458=perlquestion: print w/replies, xml ) Need Help??
mikeraz has asked for the wisdom of the Perl Monks concerning the following question:

Update: It's been pointed out that if this were not the case we'd all be:

$foo = $bar; if( $foo ) { ...
And that is not a GoodThing(tm).
#!/usr/bin/perl use strict; use warnings; my $foo = 1; my $bar = 2; if ($foo = 2) { print "foo is 2\n"; } if ($foo = $bar) { print "foo is bar two too\n"; }
I get output of:
Found = in conditional, should be == at ./tpl line 8. foo is 2 foo is bar two too
Why no warning when $foo = $bar? It's the same kind of typo error that is being caught with  $foo = 2

The question was posed on the perl-beginners email list. `man warnings` did not provide a clue. `perldoc -q` for conditional and warnings did not turn up an answer. I don't have an answer, much less a good one, for the OP.

Be Appropriate && Follow Your Curiosity

Replies are listed 'Best First'.
Re: No warning when assiging to a variable
by vsespb (Chaplain) on Aug 14, 2013 at 18:49 UTC
    It's the same kind of typo error that is being caught with $foo = 2
    it's not the same.
    if ($foo = $bar)
    is same as
    $foo = $bar; if ($bar)
    which makes some sense. while
    if ($foo = 2)
    is same as
    $foo = 2 if (2)
    which does not make much sense.
Re: No warning when assiging to a variable
by McA (Priest) on Aug 14, 2013 at 18:52 UTC


    just a guess: At compile time the compiler knows that the expression in the if statement will always evaluate to a constant 2, the if clause is probably meaningless, you get a warning. In the case of if ($foo = $bar) it may be intended, but anyway: The compiler can't evaluate the if clause to a constant as $bar can be true or false, so the conditional if may make sense.

    Best regards

      Let's have a look at what gcc does:

      /tmp>cat gcc-warn-assign.c int main(void) { int i,x,y; i=x=y=0; /* unintentional assignment inside if condition */ if (x=42) i++; if (x=y) i++; /* intentional assignment inside if condition, marked with ext +ra parentheses */ if ((x=42)) i++; if ((x=y)) i++; return i; } /tmp>gcc -Wall -pedantic gcc-warn-assign.c gcc-warn-assign.c: In function ‘main’: gcc-warn-assign.c:6:2: warning: suggest parentheses around assignment +used as truth value gcc-warn-assign.c:7:2: warning: suggest parentheses around assignment +used as truth value /tmp>gcc --version gcc (GCC) 4.5.2 Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There i +s NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR +POSE. /tmp>

      So, what do we see here?

      (Ignore i and i++, it's just dummy code.)

      Possibly unintentional assignments inside if conditions cause warnings, no matter what is on the RHS of the assignment operator. The RHS may be a constant, or any other expression. It does not matter, and it should not matter.

      If you want to write "especially clever" code, you still can assign inside an if condition without warnings, but you must wrap the assignment in semi-redundant parentheses to make your intention -- you want to test the truth of the result of the assignment -- clear to gcc. And the code is still compatible with other C compilers that do not know the extra parentheses trick, they just ignore the redundant parentheses.

      I think Perl with warnings enabled should behave the same: Warn if a variable is assigned anything, constant or not, inside the condition of if and friends, because it is likely a bug. And don't warn only if the assignment has extra parentheses indicating someone wanted to write "especially clever" code.


      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        Hi Alexander,

        Perl is not C.

        Let's look at a common idiom in Perl:

        while(my $line = <>) { do_something($line); }

        This is an assignment in a conditional operator. It does fortunately not emit a warning. Let's look at a more or less equivalent code in C:

        #include <stdio.h> #include <stdlib.h> int get_val(void); int main(void) { int i, x, y; i = x = y = 0; while (x = get_val()) { i++; printf("in loop\n"); if(i == 1) { exit(1); } } return i; } int get_val(void) { return(1); }

        Compiled with LANG=C gcc -Wall -pedantic -o warning warning.c it does emit the following:

        warning.c: In function 'main': warning.c:11: warning: suggest parentheses around assignment used as t +ruth value

        IMHO, it proves: Perl is not C, C is not Perl. C is a compiled language. Perl is a interpreted language.

        In my opinion, the above Perl idiom should not emit a warning like C does.

        Best regards

        P.S.: A ++ for your comparison.

Re: No warning when assiging to a variable
by code-ninja (Scribe) on Aug 15, 2013 at 05:23 UTC
    there is no warning because there is actually nothing to warn about. when you say $foo = $bar you're just assigning the value and there will be no conditions to evaluate. Inside an `if' conditional, the value assigned to the LHS will be used as is, like
    $bar = 2; if($foo = $bar) { # do something }
    is same as
    if(2){ # do something }
Re: No warning when assiging to a variable
by sundialsvc4 (Abbot) on Aug 14, 2013 at 19:20 UTC

    What you are asking for is a “perl lint,” which catches the stuff that is “technically legal but probably not what you wanted to do,” and I do not readily know of one.   Is there one?

    Q:  Why do computer programmers have flat heads?

    A:  (Slap!)   “D-oh!”

      Perl Critic, I suppose, is supposed to be the perl lint. It says, on brutal mode:

      No package-scoped "$VERSION" variable found
      Return value of flagged function ignored - print
      Return value of flagged function ignored - print

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1049458]
Front-paged by ww
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2017-03-29 14:08 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (351 votes). Check out past polls.