Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blocks nested too deeply

Tags:

c++

I have some untypical problem. I make available to the user sendText() function. He can type e.g.

sendText( "mytext{newline}text{up}" )

{text} is a special key that user is allowed to send. There are a lot of special keys available.

So my first step was to get the string between {} brackets and to create:

if( _specialKey == "newline" ) {
    // action for VK_RETURN
} else if( _specialKey == "up" ) {
    // action for VK_UP
} else .....

example:

if( specialKey == "n" ) {
    // enter click
    unsigned short key = VK_RETURN;
    inputs.push_back( keyDown( key ) );
    inputs.push_back( keyUp( key ) );

    return 2;
} else if( specialKey == "n+" ) {
    // enter down
    inputs.push_back( keyDown( VK_RETURN ) );

    return 2;
} else if( specialKey == "n-" ) {
    // enter up
    inputs.push_back( keyUp( VK_RETURN ) );

    return 2;
} else if( specialKey == "t" ) {
    // tabulator click
    unsigned short key = VK_TAB;
    inputs.push_back( keyDown( key ) );
    inputs.push_back( keyUp( key ) );

    return 2;
} else if( specialKey == "t+" ) {
    // tabulator down
    inputs.push_back( keyDown( VK_TAB ) );

    return 2;
} else if( specialKey == "t-" ) {
    // tabulator up
    inputs.push_back( keyUp( VK_TAB ) );

    return 2;
} else if( specialKey == "caps" ) {
    // caps lock click
    unsigned short key = VK_CAPITAL;
    inputs.push_back( keyDown( key ) );
    inputs.push_back( keyUp( key ) );

    return 2;
} else if( specialKey == "caps+" ) {
    // caps lock down
    inputs.push_back( keyDown( VK_CAPITAL ) );

    return 2;
} else if( specialKey == "caps-" ) {
    // caps lock up
    inputs.push_back( keyUp( VK_CAPITAL ) );

    return 2;
} else if( specialKey == "ralt" ) {
    // right alt click
    unsigned short key = VK_RMENU;
    inputs.push_back( keyDown( key ) );
    inputs.push_back( keyUp( key ) );

    return 2;
} else if( specialKey == "ralt+" ) {
    // right alt down
    inputs.push_back( keyDown( VK_RMENU ) );

    return 2;
} else if( specialKey == "ralt-" ) {
    // right alt up
    inputs.push_back( keyUp( VK_RMENU ) );

    return 2;
} else if( specialKey == "lalt" ) {
    // right alt click
    unsigned short key = VK_LMENU;
    inputs.push_back( keyDown( key ) );
    inputs.push_back( keyUp( key ) );

    return 2;
} else if( specialKey == "lalt+" ) {
    // right alt down
    inputs.push_back( keyDown( VK_LMENU ) );

    return 2;
} else if( specialKey == "lalt-" ) {
    // right alt up
    inputs.push_back( keyUp( VK_LMENU ) );

    return 2;
} else if( specialKey == "rctrl" ) {
    // right alt click
    unsigned short key = VK_RCONTROL;
    inputs.push_back( keyDown( key ) );
    inputs.push_back( keyUp( key ) );

    return 2;
} else if( specialKey == "rctrl+" ) {
    // right alt down
    inputs.push_back( keyDown( VK_RCONTROL ) );

    return 2;
} else if( specialKey == "rctrl-" ) {
    // right alt up
    inputs.push_back( keyUp( VK_RCONTROL ) );

    return 2;
} else if( specialKey == "lctrl" ) {

but the compiler said:

fatal error C1061: compiler limit : blocks nested too deeply

My first idea to solve it was to define a map that will store all special keys (as a string) that maps to some integer. Then I could do:

switch( map[key] ) {
    case 0:
    ...
}

but I'm not sure if the compiler won't complain about it too. There's a lot of to change, so I don't want to change it for no results.

Or maybe do you have some other better ideas?

Thanks.

like image 728
tobi Avatar asked Jul 16 '12 15:07

tobi


1 Answers

You have more than 127 else if blocks. While this ought to compile and it's certainly a bug in Microsoft's C++ compiler, it's still a pretty strong smell that something is wrong with your code.

You're storing data in your control flow, the vast majority of these 128 blocks are redundant copy and pasted blocks. You shouldn't be doing that if it's at all possible not to. Separate your code and data, use control flow for special cases while refactoring all the common cases into a single hash map that deals with it as one type.

like image 148
Gareth Davidson Avatar answered Oct 05 '22 23:10

Gareth Davidson