Arduino: Assignments != Comparisons

There is one mistake that all C programmers make, regardless of experience.  You’ll do it often when you get started, but never completely stop.  The mistake?  Confusing the “assignment” operator with the “comparison” operator.  Take a look at this line of code:

if (something = 0) {

Notice the problem?  If not, then you might fall into this common trap.  The most annoying part?  A C-Compiler won’t give an error.  That code is legal C.  Legal code doesn’t mean you’ll get the results you expect.  In fact, this is probably not even close to what you wanted.   This simple mistake and why it “works” is explained below.

= is for Assignment

First, we need to understand that C/C++ (remember Arduino is C…) uses the “=” (equal) symbol for assignments.  This means whatever is on the right side gets put into whatever is on the left side.

For example:

int foo;
foo = 100;

That code creates a variable called “foo” and then assigns the decimal value 100 to the variable. That’s the idea behind assignment.

== is for Comparison

When you want C  to compare two values, you need to use the”==” (double equal) symbol.  This says you want to compare whatever is on the right with whatever is on the left.

For example:

int foo = 100;
int bar = 100;
if (foo == bar) {
   // This code will execute...
}

In this example, we are comparing the value of foo to the value of bar.  In this example, the if statement will evaluate to “true” since foo and bar are both the same value.

Why do if-statements allow for Assignments?

Good question.  When would you want to use assignment in an if-statement?  Wouldn’t you only ever want to do comparisons?  Consider this line of code:

if (reading = digitalRead(2)) {

What will happen there?  Well:

  1. C will first call the function digitalRead(),
  2. digitalRead() checks pin 2 and returns a HIGH or LOW.
  3. The variable “reading” will become the value returned by digitalRead().
  4. The if-statement will evaluate based on the value “reading” becomes.

In other words, you aren’t evaluating if reading is the same as the value of pin 2.  Instead, you evaluate just what is in pin 2.

Here is another way to think of that code:

reading = digitalRead(2);
if (reading) {

When used correctly, this is a short cut.  However, I think most people just make it a mistake, not use it as a trick.

How to avoid it

The shortcut above is nice, but can lead to bugs.  What if you intended to compare the result of the digitalRead() to the value of reading?  When reading the code, it isn’t obvious that was the intent.  So the 2-line approach is more appropriate.

So let’s go back to the original example

if (something = 0) {

The if-statement will always evaluate to false.  You assign 0 to the variable “something” then the if-statement evaluates the value of something, which is now 0.  What if you wrote the if-statement this way:

if (0 = something) {

Now what is going to happen?  Well, the compiler is going to look at that code and laugh at you (or just throw errors).  The number 0 is a constant and you can’t assign a new value to a constant.

Logically, these two statements are the same

if (0 == something)
if (something == 0)

From a comparison point of view, you don’t care which item comes first.  However, if you use the assignment operator, the C compiler will flag the first one as a problem and prevent you from chasing down a difficult to find bug…

Conclusion

Long story short, make sure use the assignment “=” and comparison “==” operators correctly.  When code seems to “skip if statements” or “never run an if-statement”, one of the first things to check is if you misused those operators.

What’s the most annoying bug you’ve encountered, because of this simple mistake?  Leave it in the comments below.

Long comments, URLs, and code tend to get flagged for spam moderation. No need to resubmit.

ALL comments submitted with fake or throw-away services are deleted, regardless of content.

Don't be a dweeb.

Leave a comment