I have never run across two consecutive exclamation points before. if the following code had one exclamation point, I would understand it as NOT (respBuf & STCINT).
Please tell me what this code does.
#define STCINT 0x01
STC = !!(respBuf & STCINT);
It pretty much means whoever wrote that code had no idea what he was doing....
It is something like a cast to a boolean. IMHO cryptic.
!x means (x==0) so !!x means ((x==0)==0) which is (x!=0) equivalent to (bool)(x).
In C boolean logic, false is zero. True is any other value. But if you try:
SomeValue == true
then it may not actually evaluate as true because the constant
true is actually the value 1, which obviously doesn't equal any other value.
You can turn the above expression around by negating both sides:
!SomeValue == false
which will do what you intended. But not-equal-false is a strange way to look for
true. So we apply another negative to the above expression and we get...
!!SomeValue == true
Any zero in SomeValue stays zero. Any other value gets coerced/cast/changed to 1. False is false, true is true.
It's a trick. I don't use it. It's not clear to me as my reading comprehension skips ! symbols. It is also mathematically incorrect as you shouldn't compare an integer to a boolean. You should always have the same type of variable on both sides of the == sign. (You can set the compiler to warn you about this type of thing.)
SomeValue != 0
Thank you MorganS and Whandall for your useful answers. I will change those around (there are several of them) to make more sense.
If you want to ensure that any true (i.e. non-zero) value gets turned into a one (and only a one), and a false (zero) value remains a zero, then use !!.
It pretty much means that who ever wrote it knew exactly what they were doing.
I have never seen it in 'c' or 'c++'.
I think it's used in digitalWrite (I'm on my phone at the moment, so don't have source with me)
Not in digitalWrite, and I was about to write that I will eat my hat if it is in an official Arduino library, but then I found it in shiftOut() : https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_shift.c
It’s a cryptic fix for the problem of loose data type enforcement in C.
I think in the past more than ! together in code like "woo-hoo!!!" causes the compiler to do some strange things. There have been post on this in the past.
Three or more of ! (even in a string) causes interesting things to happen. I think that it is the bootloader/downloader that is affected, not the compiler. One or two get handled normally.
Its not the compiler, but some bootloaders that enter debug mode after a triple (?) exclamation mark.
The bootloader of the Arduino Mega 2560 stopped when detecting "!!!", for example when that was in a text. That has been fixed a while ago, I think with version 1.0.4. Update the bootloader of you Mega board, if you have a bootloader that is older.
That is of course something completely different than "!!" for the compiler, because the "!!" would not be in the binary resulting code.
I'm still a bit in doubt. Casting to bool is a weird thing in Arduino. Any other cast of a larger type to a smaller type result in a modulus except a cast to bool. I used to program PIC's in C and as far as I can recall a cast to bool there just resulted in a modulus into a bool (so you end up with the LSB). I'm not completely sure and I don't have the PIC C tool chain installed at the moment (nor do I have a PIC on my desk :p) so I can't check it. But the fact casting to bool reacts different then any other casting gives a a hate love relation with it. Yes, it makes things easy. But it's more compicated because you have to now it's different from any other casting. With !! you don't have that. But I think !! is a bit cryptic and easy to miss. != 0 is more clear in that way.
septillion, I agree with out. Code should be easy to read and should make sense when read out loud. Let the compiler do optimization tricks.