views:

1260

answers:

11

Today at work we came across the following code (some of you might recognize it):

#define GET_VAL( val, type ) \
    {                                                   \
        ASSERT( ( pIP + sizeof(type) ) <= pMethodEnd ); \
        val = ( *((type *&)(pIP))++ );                  \
    }

Basically we have a byte array and a pointer. The macro returns a reference to a variable of type and advance the pointer to the end of that variable.

It reminded me of the several times that I needed to "think like a parser" in order to understand C++ code.

Do you know of other code examples that caused you to stop and read it several times till you managed to grasp what it was suppose to do?

+1  A: 

C, but present in C++, I find the comma operator really obfuscates code, take this...

ihi = y[0]>y[1] ? (inhi=1,0) : (inhi=0,1);

Terse and quite elegant, but very easy to miss or misunderstand.

Simon
To me, this code is a perfect example of "Just because you can do something, doesn't mean you should." It's neat because it's on one line, but if it was spread out more it would be many times more understandable by someone look at it for the first time.Not that it's not a cool example. :)
Colen
+5  A: 

I know it's C and not C++ but there is always the the International Obfuscated C Code Contest. I have seen some code there that would make your head spin.

wcm
+6  A: 

This is well known but still impressive way to swap two integers without creating temp variable:

// a^=b^=a^=b;     // int a and int b will be swapped
// Technically undefined behavior as variable may only 
// be assined once within the same statement.
// 
// But this can be written correctly like this.
// Which still looks cool and unreadable ;-)

a^=b;
b^=a;
a^=b;
Ma99uS
only problem is that this is technically undefined behavior due to sequence point rules. use "a ^= b; b ^= a; a ^= b;" instead.
Evan Teran
Wrong. it is correct. Operation order is perfectly defined from right to left in this case. Read the standard,
Terminus
@ Terminus: You are infact wrong. Assigning to a variable more than once in a statement is undefined behavior. To prevent this you need to use the ';' to seporate them into different statements.
Martin York
Actually you need to study the C/C++ standard. Why do you state things you don't know about? Read about associativity: http://www.cppreference.com/wiki/operator_precedence '=' has right to left associativity. This site is supposed to give EXPERT answers. You just demonstrate your ignorance in C/C++.
Terminus
This is realy really really basic stuff. You shouldn't be talking about C/C++ when you don't know this. You are just spreading false ideas.
Terminus
You can also read here some stuff: http://en.wikipedia.org/wiki/Operator_associativity#Note_about_right-associative_operators
Terminus
int a = 10, b = 45;a^=b^=a^=b;std::cout << a << "\t" << b;That gave the correct output: 45 10
Esteban Brenes
@Terminus: The problem has nothing to do with associativity. The problem is with sequence points.http://en.wikipedia.org/wiki/Sequence_point. Unfortunately Sequence points and optimizations are really complex stuff and you need to be a compiler engineer to really understand them (like myself).
Martin York
@Esteban: The behavior is undefined. This means the compiler may or may not do the correct thing, and could even change depending on the optimization level you are using.
Martin York
@Martin: Yes, you are 100% right. I thought only about associativity and neglected sequence points. You can't modify the same variable twice between 2 sequence points. You are 100% correct :-). Sorry about the noise.
Terminus
You can still use the comma operator if you want to do all that in a single instruction, though ;-).
Terminus
@Martin: Cool, thanks for clearing that up!
Esteban Brenes
Wow! Who could of thought that such simple expression will raise such complicated debate :-)P.S. for ignorant VC++ coder the original form works fine though.
Ma99uS
@Ma99uS: It may look and work fine (See Esteban's comments above). But technically it is undefined. The compiler is free to do anything it likes. Assuming VC++ implements C++.
Martin York
+1  A: 

Binary shifts confuses me all the time:

An example from java.util.concurrent.ConcurrentHashMap:

return ((h << 7) - h + (h >>> 9) + (h >>> 17))

Shimi Bandiel
Why has this been voted up? This is Java, but the question is about C++.
finnw
+11  A: 

This was on reddit recently http://www.xs4all.nl/~weegen/eelis/analogliterals.xhtml

 assert((o-----o
        |     !
        !     !
        !     !
        !     !
        o-----o ).area == ( o---------o
                            |         !
                            !         !
                            o---------o ).area );
Martin Beckett
this is a tautology.
Haoest
Now *this* is why I love C++ !
Luc Touraille
+5  A: 
unsigned int reverse(register unsigned int x)
{
 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
 return((x >> 16) | (x << 16));
}

Reverses the order of the bits in an int.

mbeckish
If this had been clever trick code then +1.
Martin York
A: 

I vote for some black-magic-hackerish template metaprogramming (unfortunately don't have any on hand to post it).

Kasprzol
+10  A: 

Duff's Device (http://en.wikipedia.org/wiki/Duff%27s_device) give me nightmares:

strcpy(to, from, count)
char *to, *from;
int count;
{
    int n = (count + 7) / 8;
    switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
               } while (--n > 0);
    }
}
Matt Rogish
I've always found Duff's Device quite intuitive, it just makes sense. After you get over the weird syntax of the loop you're rolling, or unrolling perhaps :)
PintSizedCat
I think this is easier to understand if you've programmed assembly than if you've come from a non-assembly background.
Skizz
+2  A: 

Most Boost stuff - the template metaprogramming is bad enough, but when you factor in the workarounds necessary to get it to work on some compilers (*coughborlandcough*), it gets pretty ridiculous. Just try to understand Boost.Bind. Just try.

coppro
+7  A: 

The inverse square root implementation in Quake 3:

float InvSqrt (float x){
    float xhalf = 0.5f*x;
    int i = *(int*)&x;
    i = 0x5f3759df - (i>>1);
    x = *(float*)&i;
    x = x*(1.5f - xhalf*x*x);
    return x;
}

Update: How this works (thanks ryan_s)

Ates Goral
Don't forget to link Chris Lamont's paper for the great explanation of how this crazy thing works.http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
ryan_s
A: 

Anything prefixed with:

/* You are not expected to understand this */

Skizz