How long does it take you to grok this code?

by Michael S. Kaplan, published on 2005/09/16 19:42 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2005/09/16/469651.aspx


You have to be honest if you want to play on this one. :-)

Look at the snippet of code below, and tell me how long it takes you to grok the intent:

if (!((dwFlags & (GLOBAL_FLAG1 | GLOBAL_FLAG2)) && (!(dwFlags & GLOBAL_FLAG3)))) {
    break;
}

I got it, but it really did take me a couple of minutes and a white board.

This is not an interview question I would ever give, but it is of a type that I have been given once or twice....


# Maurits [MSFT] on 16 Sep 2005 8:09 PM:

break if flag three is on.
break if flags one and two are both off.

(I despise negative assertions...)

A simpler rewrite:

if (dwFlags & GLOBAL_FLAG3) { break; }
if (dwFlags & (GLOBAL_FLAG1 | GLOBAL_FLAG2) == 0) { break; }

# CornedBee on 16 Sep 2005 8:31 PM:

One minute, but I've got a lot of practice in this.

# James Todd on 16 Sep 2005 9:42 PM:

30 seconds.

Really. I used my stopwatch.

If the flags have (FLAG1 and FLAG2), and it does NOT have FLAG3, then continue. Otherwise, break.

# Centaur on 17 Sep 2005 1:00 AM:

Did not time, but I think I did it in under a minute. Although I’d say either the condition or its two subconditions want to move into separate boolean functions (possibly leaving the outermost ! and && behind).

if (!predicate1(dwFlags) || !predicate2(dwFlags)) break;

# An Phu on 17 Sep 2005 1:11 AM:

Maurits got it right.

It took me notepad.exe and two minutes.

# Maurits [MSFT] on 17 Sep 2005 2:29 AM:

;)

# Mike Weller on 17 Sep 2005 5:01 AM:

30 seconds, but it's not really that hard if you've done alot of this stuff.

# Tim Smith on 17 Sep 2005 10:46 AM:

Maurits goofed. His second statement should be:

if ((dwFlags & (GLOBAL_FLAG1 | GLOBAL_FLAG2)) == 0) { break; }

If you don't mix your logical operators with numeric results and use the !(a&b) = (!a|!b) rule, you can write:

if ((dwFlags & (GLOBAL_FLAG1 | GLOBAL_FLAG2)) == 0 || (dwFlags & GLOBAL_FLAG3) != 0)
{
break;
}

while is much easier to read in my opinion.

# Maurits [MSFT] on 17 Sep 2005 11:43 AM:

Yup, == binds more tightly than &. My bad.

# Adi Oltean on 20 Sep 2005 3:45 AM:

>>> if (!((dwFlags & (GLOBAL_FLAG1 | GLOBAL_FLAG2)) && (!(dwFlags & GLOBAL_FLAG3)))) {
break;
}

Whenever I see (!(expr1 && expr2)) I immediately try to reduce it as (!expr1 || !expr2).

In our case, this helps a lot since expr2 already contains !, so the original "if" statement simplifies to:

if ((dwFlags & (GLOBAL_FLAG1 | GLOBAL_FLAG2) == 0) || (dwFlags & GLOBAL_FLAG3))) {
break;
}

which says that if either dwFlags doesn't contain both FLAG1 & FLAG2, or if dwFlags contains FLAG3, then break.

Generally, an expression is easier to follow up if you reduce it to the normal form:

(expr11 && expr12 && ... )
|| (expr21 && expr22 && ... )
...
|| (exprN1 && exprN2 && ... )

Tanveer Badar on 30 Dec 2007 8:38 AM:

~25 seconds. I had to read three times highlighting various parenthesis with mouse.

But then, I also finished Harry Potter and the Deathly Hallows in 10:45 hours. :)


Please consider a donation to keep this archive running, maintained and free of advertising.
Donate €20 or more to receive an offline copy of the whole archive including all images.

go to newer or older post, or back to index or month or day