C#: Did if( a = b) lose its sting


One of the common typo of using if (a = b) in place of if (a == b) gave a lot of grief to programmers working in C and C++. If you make the typo, you have an expression that is always true if b is not 0 (mostly it isn't) and the compiler is not even polite enough to warn you. So many people taught themselves to use the inverted comparison as in

int a = 1;

if(a == 2)

printf("Hello");

if (2 == a) // inverted

printf("Hello");


People believed the inverted comparison was better because if you typed = instead of == you'd get a compilation error indicating that the "left operand of = must be a lvalue". I always thought that a person who remembers to type the inverted expression will anyway remember to not-type = in place of ==. I felt uneasy to see expressions this way.


C# allows only boolean expression for comparison. This almost removed the chances of the typo to exist. You can make the same typo only if a is a boolean type. So the following code will fail to compile in C#

int a = 1;

if (a = 2)

Console.WriteLine("Yea");


Stating "Cannot implicitly convert type 'int' to 'bool'". So this virtually eliminates the chances of the typo leading to a bug. In case you do have something as below

bool cond = false;

bool othercond = true;

if(cond = othercond)

Console.WriteLine("Yea");


it can potentially lead to a bug if you did not intend the =. As again there is no warning and one bug just sneaks in. Before this leads you to believe that a bug can sneak in only if the lvalue is boolean you need to carefully look at following

class MyClass

{

public static implicit operator bool(MyClass mc)

{

return true;

}

}


MyClass
mc1 = new MyClass();

MyClass mc2 = new MyClass();

if (mc1 = mc2)

Console.WriteLine("Yea again");


This will compile without an warning because the class has an implicit cast to bool.  The compiler will not complain and you again have the same sneaky bug in your code.

Comments (7)

  1. Damien Guard says:

    Implicit operators seem more trouble than they are worth.

    Another problem you get with them is that the implicit part is performed on the false part of a conditional operator.

    e.g. return (a == null) : null ? a.something();

    if something has an implicit operator this will blow up when a is null….

    [)amien

  2. ricster says:

    surely it can’t be that difficult to have a compiler that can check if a single "=" exists within a "()" block, maybe check for the "if" too?

    but make it optional, because sometimes you want to do it:

    if( !(obj1 = getObject()) )

    {

    //error: failed to allocate memory for object obj1;

    }

  3. Assignments inside conditional statements makes for harder to read code.

    It’s too bad they didn’t remove the boolean assignment inside conditionals as well but it’s a step in the right direction.

  4. tzagotta says:

    I agree with Kristoffer – it would have been nice if they were removed from the language alltogether. An assignment statement should not return a value, period. It is the source of bugs like the one being discussed, and it enables bad coding style.

  5. SEan says:

    I want to point out that the last two examples are’t necessarily bugs.. it could be a perfectly valid statement if you wanted to base the condition on the value of the second argument and set the value of the first to the second… sloppy definately, but still a valid logical expression.

  6. Sean, what you say is absolutely correct. Thats why I said "it can potentially lead to a bug if you did not intend the =".

    The point of the discussion is how may times in code do you really intend to have an assignment in a conditional expression. If you do use it regularly, you are kind of being unfair to the maintainer of the code. Think about a person who steps in after a year going through 1000’s of lines of code trying to fix a bug. He might just miss that statement….

    For clarity its best to split it into two statements.

  7. One of the blogs i’ve been reading a lot lately is I know the answer (it’s 42). I’ve added it to my Reader…

Skip to main content