Boolean Math

I just had a sketch blow up when using a newer version of the compiler. I assume I was, once again, the victim of bad code that worked for no particular reason...

I was repeatedly loading a two place array with incoming characters. Those two characters were then transformed into a numerical hex value. For the index of that two place array, I was using a boolean called byteIndex.

I was relying on byteIndex++; to rollover to 0 if it was 1, using the same logic that adding 1 to a uint8_t of 255 = 0.

What was wrong with my logic?

Thanks,

John

No, it won't roll over from 1 to 0;
Try this instead:-
byteIndex^=1;orbyteIndex=!byteIndex;

You should not do math operations on Boolean - only Boolean operations

If your Boolean was true and you wanted to get to the opposite value then the Boolean operator is 'not' which your represent in code with !

A = true;
B = !A; // B is false

Steve and JML, thanks for the help.

Carrying the thought a bit farther… would it be considered poor style or technique to use a boolean type for a value, such as an index?

Definitely very poor :slight_smile:

An index in general by meaning is a number not a truth statement

it is an arbitrary programming language convention to have false at 0 and true at 1. Good compilers and pre-processors will bark at you with type mismatch if you try to access an array with a Boolean as an index

if you want to optimize memory usage because you know it's less than 255 you can use a byte and for larger values use unsigned int or unsigned long depending on your requirements

J-M-L:
it is an arbitrary programming language convention to have false at 0 and true at 1.

You may want to consult the C++ language standard before making such claims.

J-M-L:
Good compilers and pre-processors will bark at you with type mismatch if you try to access an array with a Boolean as an index

In C++ bool is an ordinal datatype like char, int, and long.

@Coding badly

An example is not a proof of general case. As a counter example, CAML would bark at you if you were trying to do math operations with booleans.

Yes C++ fully defines Boolean promotion into int as 0 and 1 (bool values behave as integral types and participate in integral promotions). I maintain this is arbitrary decision taken by the designers, they could have chosen something different.

Often one associates true to correct and false to error. Now - Take C functions or UNIX/shell commands that return zero when all was correct, you could say this feels weird because if all went well the function should give you a positive truth answer -but because you want to be able to return different error codes, then the convention has been 0 is all ok and anything else is error.

As I said it is language dependent. While it is safe to make such assumption in C++ because it is properly documented (and in many languages) it is still a bad conceptual shortcut (that we often take)

J-M-L:
I maintain this is arbitrary decision taken by the designers, they could have chosen something different.

arbitrary:
arbitrary - based on random choice or personal whim, rather than any reason or system.

The C++ standards group did not roll dice to make that decision.

However, it makes no difference. They defined bool they way the did which makes bool a reasonable choice for an array index.

As a counter example, CAML would bark at you if you were trying to do math operations with booleans.

The question at hand is whether or not C++ bool is a reasonable choice for an array index. Do try to stay on-topic. Ditto for the rest of your post.

Fair enough on the exact terminology of arbitrary. There is some rationale behind it I'm sure - but how much of it is inertia/backward compatibility with c which had not conceptual type for Boolean. If you know I would be interested in knowing why we have this originally? Switch/transistor closed versus open?

Is it OK to disagree with a 5 star general here? :slight_smile:

His last question was

Carrying the thought a bit farther... would it be considered poor style or technique to use a boolean type for a value, such as an index?

I took that as a general question on programming, not a C++ related question - hence my comment.

To go back to the very first question and in C++

I do believe the original code should indeed alternate between true and false (and personally see that as bad intellectual practice in general case)


A prvalue of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to a prvalue of type bool. The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false. All other values become true.

J-M-L:
I do believe the original code should indeed alternate between true and false

No, it doesn't. Try this:-

boolean byteIndex=0;

void setup()
{
    Serial.begin(115200);
}

void loop()
{
    Serial.println(byteIndex);
    byteIndex++;
    delay(500);
}

It prints:-

0
1
1
1
1
1
1
etc

No rollover from 1 back to 0.

Sorry yes you are 100% right, I don't know what I was thinking - as my quote stated Indeed the C++ definition states that any non zero will go back to true so 1 when you increment.

J-M-L:
Sorry yes you are 100% right, I don't know what I was thinking - as my quote stated Indeed the C++ definition states that any non zero will go back to true so 1 when you increment.

Yeah, you'd sort of expect that it would roll over like, for example, 'byte' in the following code, but not so unfortunately. :frowning:

byte val = 250;

void setup()
{
    Serial.begin(115200);
}

void loop()
{
    Serial.println(val);
    val++;
    delay(500);
}

There is a great Wikipedia article on the topic discussing languages