63 votes

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

J'obtiens une erreur "transfer of control bypasses initialization of :" lorsque j'essaie de construire 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 l'appel de ma fonction enumerate. S'il n'est pas permis d'appeler une fonction à partir d'un commutateur, existe-t-il une solution de rechange pour ce type de problème ?

109voto

Sam Miller Points 14976

Section 6.6.4 de la norme C++ :

L'instruction goto est inconditionnelle transfère inconditionnellement le contrôle à l'instruction marquée par l'identifiant. Le site identificateur doit être une étiquette (6.1) situé dans la fonction courante.

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 initialisation . A programme qui saute d'un point où une variable locale à durée de stockage automatique automatique n'est pas dans le champ d'application point où elle l'est, est mal formé, sauf si la variable est de type POD (3.9) et soit déclarée sans un initialisateur

Accent mis sur ajouté par moi. Depuis switch est vraiment goto déguisé, vous rencontrez ce comportement. Pour résoudre ce problème, ajoutez des accolades si vous devez utiliser une balise switch

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

ou de 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 de savoir ce que vous espérez accomplir avec la création d'un site web. windows vector à l'intérieur d'un switch donc vous devrez peut-être repenser votre conception. Note J'ai ajouté un const qualificatif pour windows puisqu'il n'est pas modifié dans votre exemple.

16voto

Armen Tsirunyan Points 59548

Un commutateur est essentiellement un goto c'est-à-dire qu'il s'agit d'un goto à l'étiquette appropriée. La norme C++ interdit un goto pour contourner l'initialisation d'un objet non-POD. Mettez la déclaration du vecteur 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
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X