你知道什么是最难理解的C++代码?

Dro*_*per 19 c++

今天在工作中我们遇到了以下代码(你们中的一些人可能认识到它):

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

基本上我们有一个字节数组和一个指针.宏返回对类型变量的引用,并将指针前进到该变量的末尾.

它让我想起了几次我需要"像解析器一样思考"才能理解C++代码.

您是否知道其他代码示例导致您多次停止并阅读它,直到您设法掌握它的假设?

Ate*_*ral 41

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;
}
Run Code Online (Sandbox Code Playgroud)

更新: 这是如何工作的(感谢ryan_s)

  • 你为什么不包括评论:( (2认同)

Mar*_*ett 29

这是最近的reddit http://www.eelis.net/C++/analogliterals.xhtml

 assert((o-----o
        |     !
        !     !
        !     !
        !     !
        o-----o ).area == ( o---------o
                            |         !
                            !         !
                            o---------o ).area );
Run Code Online (Sandbox Code Playgroud)

  • 现在*这就是我爱C++的原因! (3认同)
  • 链接现已损坏:( (2认同)
  • @JaredBurrows - 谢谢,发现了一个新的 (2认同)

Mat*_*ish 15

Duff的设备(http://en.wikipedia.org/wiki/Duff%27s_device)让我做恶梦:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


wcm*_*wcm 11

我知道它是C而不是C++,但总是有国际混淆的C代码竞赛.我在那里看到了一些会让你头晕目眩的代码.


mbe*_*ish 10

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));
}
Run Code Online (Sandbox Code Playgroud)

反转int中位的顺序.


Ma9*_*9uS 9

这是众所周知但仍然令人印象深刻的方式来交换两个整数而不创建临时变量:

// 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;
Run Code Online (Sandbox Code Playgroud)

  • @Terminus:你真的错了.在语句中多次分配变量是未定义的行为.要防止这种情况,您需要使用';' 把它们分成不同的陈述. (3认同)
  • @Terminus:问题与关联性无关.问题在于序列点.http://en.wikipedia.org/wiki/Sequence_point.不幸的是,序列点和优化是非常复杂的东西,你需要成为一名编译工程师才能真正理解它们(比如我自己). (3认同)
  • 唯一的问题是,由于序列点规则,这是技术上未定义的行为.使用"a ^ = b; b ^ = a; a ^ = b;" 代替. (2认同)
  • @Esteban:行为未定义。这意味着编译器可能会或可能不会做正确的事情,甚至可能会根据您使用的优化级别进行更改。 (2认同)
  • @马丁:是的,你是100%正确的。我只考虑了关联性和被忽略的序列点。您不能在2个序列点之间两次修改同一变量。您是100%正确的:-)。对不起,噪音。 (2认同)

cop*_*pro 6

大多数Boost的东西 - 模板元编程很糟糕,但是当你考虑到让它在某些编译器(*coughborlandcough*)上工作所必需的变通方法时,它就变得非常荒谬了.试着去了解Boost.Bind.试一试.