web-dev-qa-db-fra.com

passer "le transfert de contrôle contourne l'initialisation de:" lors de l'appel d'une fonction

J'obtiens une erreur de "transfert de contrôle qui contourne l'initialisation de:" lorsque j'essaie de créer le commutateur suivant:

switch (retrycancel)
{
    case 4:    //The user pressed RETRY
        //Enumerate all visible windows and store handle and caption in "windows"
        std::vector<MainHandles::window_data> windows = MainHandles().enum_windows().get_results(); 
        break;

    case 2: 
        //code
}

Cela a quelque chose à voir avec mon appel à ma fonction d'énumération. S'il n'est pas autorisé d'appeler une fonction à partir d'un commutateur, existe-t-il une solution pour ce type de problème?

49
Lumpi

section 6.6.4 de la norme C++:

L'instruction goto transfère inconditionnellement le contrôle à l'instruction étiquetée par l'identifiant. L'identifiant doit être une étiquette (6.1) située dans la fonction actuelle.

section 6.7 de la norme C++:

Il est possible de transférer dans un bloc, mais pas d'une manière qui contourne les déclarations avec l'initialisation. Un programme qui passe d'un point où une variable locale avec une durée de stockage automatique n'est pas dans la portée à un point où elle est dans la portée est mal formé sauf si la variable a le type POD (3.9) et est déclarée sans initialiseur

Souligné ajouté par moi. Puisque switch est vraiment goto déguisé, vous rencontrez ce problème. Pour résoudre ce problème, ajoutez des accolades si vous devez utiliser un switch

switch (retrycancel)
    {
    case 4:
    {
        const std::vector<MainHandles::window_data> windows(
            MainHandles().enum_windows().get_results()
        );
        break;
    }
    case 2: 
        //code
    }

ou refactoriser en if/else

if (retrycancel == 4) {
    const std::vector<MainHandles::window_data> windows(
        MainHandles().enum_windows().get_results()
    );
} else if (retrycancel == 2)
    // code
} else {
    ...
}

Bien qu'il ne soit pas évident pour moi ce que vous espérez accomplir avec la création de windowsvector à l'intérieur d'un switch, vous voudrez peut-être repenser votre conception. Note J'ai ajouté un qualificatif const à windows car il n'est pas modifié dans votre exemple.

74
Sam Miller

un commutateur est essentiellement un goto, c'est-à-dire qu'il s'agit d'un goto de l'étiquette appropriée. La norme C++ interdit à un goto de contourner l'initialisation d'un objet non POD. Prenez la déclaration vectorielle entre accolades et cela résoudra le problème

switch (retrycancel)
    {
     case 4:                //The user pressed RETRY
     {
        std::vector<MainHandles::window_data> windows = MainHandles().enum_windows().get_results(); //Enumerate all visible windows and store handle and caption in "windows"
        break;
     }
    case 2: 
        //code
    }
11
Armen Tsirunyan