Not understanding toggle code

AWOL:
Interestingly, even if the API says only HIGH or LOW are allowed, the implementation of 1.0 only tests for LOW.

But technically, the digitalWrite() API never says that HIGH and LOW are the only allowed values,
(it's current C code declaration can't stop you from passing other values)
The API only makes a commitment as to what behavior to expect when the values are HIGH or LOW.
The behavior for other values are undefined in the API.

Garbage in, Garbage out right????

It is why I mentioned earlier that there are "working" code examples out there in the forum posts
and in libraries that are using 0 and non zero to set the output pin state.

They work because the current AVR arduino code in digitalWrite() only checks for LOW
and sets the output pin to a logic high level when the value passed is not LOW.

With todays AVR Arduino dititalWrite() code implementation,
you can get away with assuming HIGH is 1 and LOW is 0
and that zero sets a output pin to low and any other non zero value sets the output pin to a logical
high.

But I like to write and encourage others to write portable code that does
not depend on internal implementation details that are not part of the formal API
definition.

This is why I stress that using internal implementation details is dangerous as
some other implementation on some other processor
say ARM, pic32, etc... might not implement the code the same way or make the same assumptions
or the underlying code might change in the future.

The reality of things at this point, is that there is so much existing code out there
that didn't stick to the formal APIs that if you now were to change something like this,
some amount of the code will break, and that is why the core developers like Diligent/chipkit and Maple
have implemented their DigitalWrite() routines with the same HIGH/LOW values and assumptions.

Still, it's never a bad thing to try to encourage folks to stick to API definitions.

That said, there are sometimes legitimate uses to violate an API spec or take advantage
or internal details.
So I will admit there are times when you do want to intentionally violate the API spec.
Perhaps by taking advantage of knowing how the API works or the values of its defines
you can optimize the code to some higher needed level.
But usually when deciding to do this it is a path carefully taken knowing that in doing this,
it may create a portability issue in the future.

That would apply in this particular case if you were looking to squeeze a few cycles or
flash bytes out.

If you look at the AVR code generated, you can generate better/faster code
if you can take advantage of knowing that HIGH is 1 and LOW is 0.
For example;

 state ^= HIGH;

and this

state ^= state;

Is more efficient than

if(state == HIGH)
  state == LOW;
else
  state == HIGH;

It will generate fewer AVR instructions which will be less/faster code.

(The subtract method gives a gcc warning as I assume
it is worried about overflows/underflows)

But doing things like this come with added risk that if ever the defines change,
the code may stop working as expected.
Or it may not generate better code on some other CPU architecture.

So, in general, that is why I try do discourage people from writing code that
takes advantage of internal API implementation details.
It just not good programming practice to ensure long term portability.

--- bill