I was just reading the definition of assert in assert.h and basically it was this :
My question is why are there 2 ! operators ? isn't that the same as saying
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
Sorry if this was a stupid question, but it was just confusing me. Thanks!
#define assert(_Expression) (void)( (_Expression) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
!0 is 1
!anything else is 0
!!0 is 0
!!anything else is 1 (by statement 1 and 2)
So are you saying the !! is useless here? Any non-zero value is true, so converting them to 1 shouldn't make a difference.
Originally Posted by Salem
I saw a !! in code I was modifying a while ago and I just removed it since it was pointless.
In this context, it is useless.
But it's not entirely useless here...
If _Expression were of type <someClass> and that class did not provide a cast operator giving an implicit conversion to bool or etc, but it did have an operator !, then the code with !! works and the code without it doesn't. Does that description make sense or should I post a code sample?
That is precisely why the macro is written like that. It's just one more scenario that it will work for, however obscure that scenario may be.
The scenario is not that obscure.
Originally Posted by iMalc
Several coding standards specifically disallow classes supporting any conversion to a basic type (or to raw pointers) because those conversions can happen implicitly (i.e. the compiler does the conversion) in circumstances where such a conversion is unwanted by the programmer.
However, supporting an operator!() is not forbidden in such cases: an operator!() cannot be accidentally invoked.
But why would you want to do that?
I can see why you would overload ! for say 'class mybool', but that would be overloading the data within the object, not somehow asserting the validity of the class object to begin with.
Likewise, for say 'class vehicle', what would overloading the ! operator achieve? It doesn't seem to make sense to overload it "just because I can / just in case I use assert".
assert( car ); // huh?
If you couldn't construct the class instance to begin with, then shouldn't you have thrown an exception? Rather than relying on the caller to use assert (which is a debug-only thing anyway).
Please post your example.
Smart pointers. Of course, I expect any good smart pointer to use the safebool idiom to be usable in conditions, but weird company policies may be in place.
There is another, more likely reason to use the double-not. It may avoid compiler-specific warnings.
Actually I'm still not back on my own computer so I wont post the example I had in mind. I was thinking of a bigint class, but yes a smart pointer class also fits.
In fact, as CornedBee referred to, I remembered that I use the safe-bool idiom nowdays anyway.