(A==B)==(X==Y)
I used to hate the expression: (A==B)==(X==Y), but I've grown very fond of it.
My prior feelings of contempt stem from my desire to avoid obscure language features. But I figure when properly parenthesized, this isn't so obscure and can be pretty useful and concise. Unlike operator precedence, you don't need to go lookup a table to parse it.
Where is this useful?
I find it's really useful for concisely checking that multiple values are in sync. For example, asserts like this:
Foo * p;
HRESULT hr = GetFoo(&p);Assert(SUCCEEDED(hr) == (p != NULL) );
In this case, either the function succeeded and gave you back a non-null object; or it failed and gave you a null-object. (This is of course assuming that's GetFoo's contract. Some functions leave their out-parameters undefined on failure).
Or this:
void SomeStringFunction(const BYTE * pBuffer, DWORD cbLength) {
Assert( (pBuffer == NULL) == (cbLength == 0) );
This asserts that either you have a pointer to a non-zero-length buffer or you don't have anything at all.
Comments
Anonymous
September 20, 2007
I am no compiler but what about pBuffer = NULL and cbLength = NULL? Assert((true) == (true)); Assert(true); // nothing happens althouth the input is bad. If I read this right it will slip through your Assert. Yours, Alois KrausAnonymous
September 21, 2007
I should have been clearer, when I said: "This asserts that either you have a pointer to a non-zero-length buffer or you don't have anything at all." Lots of functions tend to take a buffer as (pointer, size), and optionally allow the buffer to be empty. (Eg, maybe it will write something to the buffer if provided). How do you supply an empty buffer? Just a null pointer? Just a 0 size? To be defensive, it's nice to require both pBuffer == NULL and cbLength == NULL. So then you have 2 valid options: pBuffer == NULL && cbLength == NULL; // empty buffer pBuffer != NULL && cbLength != NULL; // valid buffer Rather than assert Assert((pBuffer == NULL && cbLength == NULL) || (pBuffer != NULL && cbLength != NULL)); I think it's easy to say Assert((pBuffer == NULL) == (cbLength == NULL));Anonymous
September 21, 2007
Until VB.NET, VB still had the Eqv boolean operator. Which allowed you to write : (A=B) Eqv (X=Y) The result being strictly the same but perhaps slightly more readable ?