开发者

Why is std::bitset::at() throwing out_of_range?

开发者 https://www.devze.com 2023-04-08 15:30 出处:网络
This has stumped me for a few hours now, since I cannot see any problem in the math or code.(Dispite staring at it and working it out over and over again to be sure.)I\'m hoping you folks can help me,

This has stumped me for a few hours now, since I cannot see any problem in the math or code. (Dispite staring at it and working it out over and over again to be sure.) I'm hoping you folks can help me, here's my code:

#define SOLVE_POSITION(x, y, z) ( z*16  +  y*4  +  x )

std::bitset<64> block;
block.reset();

for(int z = 0; z < 4; ++z){
    for(int y = 0; y < 4; ++y){
        for(int x = 0; x < 4; ++x){

            if(block.at(SOLVE_POSITION(3-x, y, 3-z))){  //<-- call to at() throws 'out_of_range'

                // do stuff
            };
        };
    };
};

With z being 0, the two inner most for loops run their course entirely (for a total of 16 passes.) However, once z becomes 1, that's when the exception is thrown from within std::bitset<64>::at().

The values of z, y, x开发者_JS百科 are respectively 1, 0, 0 at that moment.

Can you tell me what is happening here to cause this exception? Thanks in advance!


Macros! You have to be really careful about this:

You define:

#define SOLVE_POSITION(x, y, z) ( z*16  +  y*4  +  x )

so when you do:

SOLVE_POSITION(3-x, y, 3-z)

it expands to:

( 3-x*16 + y*4 + 3-z )

and because of operator precedence, 3-x*16 will be incorrect! You need to do:

#define SOLVE_POSITION(x, y, z) ( (z)*16  +  (y)*4  +  (x) )

so that it expands correctly to:

( (3-x)*16 + (y)*4 + (3-z) )

as expected.


Macros use text substitution, you're effectively telling the compiler

SOLVE_POSITION(3-x, y, 3-z) => SOLVE_POSITION( 3-z*16  +  y*4  +  3-x )

To fix this, make sure you surround your macro arguments with parenthesis:

#define SOLVE_POSITION(x, y, z) ( (z)*16  +  (y)*4  +  (x) )
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号