Why not use: x = !x;?

Experts,

I noticed on the page: Blink Without Delay here, the authors used:

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

...but wouldn't this be faster?

ledState = !ledState;

Is there a reason for extra lines?

No. Both codes will compile to the same binary

1 Like

They explain the operation in self-documentary terms. Personally, I like:

ledState = not ledState;

Wow! I always naively thought less source = less compiled.

Thanks!

That was true, before optimizing compilers came along.

@aarg Thanks for the replies.

Fast can be good, but it doesn't help beginners to understand.
How do I know? Correct, I'm a beginner.
Good question, that's just my take on it.

I don't think there is equivalence.

HIGH and LOW are BOOLEAN values and not specified in the reference as integral values, so it very much depends on what type of variable ledState is defined.

digitalWrite takes LOW or HIGH. You happen to know that they are actually zero and one respectively, so tricks treating them as boolean will work as expected.

In this case it's harmless, but it's generally a really bad idea to rely on what you know about how something is implemented because you have no guarantee that it will never change.

3 Likes

I prefer that the sketch shows what it is doing.
The 'not' or the '!' is a logical operation and a 'bool' type is a logical variable. That makes sense.
The function digitalWrite() uses HIGH and LOW. Some say they are 1 and 0 and the same as true and false, but that is not correct for all Arduino board and that is not mentioned in the documentation.

I'm with @wildbill. Don't try to be too smart. Don't make shortcuts. Don't assume things that are not mentioned in the documentation. Don't show off with trickery compressed slimy code.

1 Like

As a side note, we sometimes need -1 and +1
This can be used to decrement/increment a variable.

int direction  = 1;
. . .
myVar = myVar + direction;
. . .
if(myVar > 99)
{
  direction = 0 - direction;  //change direction
  myVar = 99;
}

else if(myVar < 0)
{
  direction = 0 - direction;  //change direction
  myVar = 0;
}

direction = -direction;

Example: https://wokwi.com/arduino/projects/302463012690723341
[ADDED]
Now that I look at my example, it doesn't even use direction = -direction :woozy_face:

For new users the above might make more sense as it visually shows intention, just saying . . .

No, they are integer values

2 Likes

Perhaps they should be boolean.

Why?
If you're using a pullup resistor on a switch, what Boolean value do you use to indicate that the switch is closed / operated?

Isn’t it obvious, 1 and 0 :nerd_face:

image

2 Likes

What is even trickier, in some of the newer board packages HIGH and LOW are an enum. This initially broke some existing code when first introduced.

typedef enum {
  LOW     = 0,
  HIGH    = 1,
  CHANGE  = 2,
  FALLING = 3,
  RISING  = 4,
} PinStatus;
2 Likes

Yes. Because there is no assurances as to what HIGH and LOW really are and the code should not make any assumptions about what type they are or their values.

While most implementations define HIGH as 1 and LOW as 0, it is not required.
So to ensure that the code is portable and will always work/compile across all Arduino core implementations including past and future versions, this code makes no assumptions about the values or type for HIGH and LOW, which is the safest and most reliable thing to do.

To assume a specific implementation is abusing the API since there is no assurances as to what / how HIGH and LOW are defined / declared.
They are never defined in the Arduino documentation.

I believe at one point Arduino.cc was going to change HIGH and LOW from simple defines to specific type or enum. In that case, using something like

ledState = !ledState;

would break since it would not compile.

Note:
Treating HIGH and LOW as 1/0 or true/false as been discussed many times on the forum. While it typically works, it is abusing the API and is not guaranteed to work and should be avoided.

--- bill

1 Like

It's not any worse than "what HIGH/LOW value do you use" for that.