(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 (3)

  1. Alois Kraus says:

    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 Kraus

  2. 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));

  3. 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 ?

Skip to main content