<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>Kévin Subileau &#187; variable</title> <atom:link href="http://www.kevinsubileau.fr/tag/variable/feed" rel="self" type="application/rss+xml" /><link>http://www.kevinsubileau.fr</link> <description>Espace personnel</description> <lastBuildDate>Sun, 02 Feb 2020 15:18:58 +0000</lastBuildDate> <language>fr-FR</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>C++ : Déclarer une variable dans un switch</title><link>http://www.kevinsubileau.fr/informatique/boite-a-code/c-cpp/cpp-declarer-variable-switch.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rss</link> <comments>http://www.kevinsubileau.fr/informatique/boite-a-code/c-cpp/cpp-declarer-variable-switch.html#comments</comments> <pubDate>Sat, 11 Jan 2014 19:20:13 +0000</pubDate> <dc:creator>Kévin Subileau</dc:creator> <category><![CDATA[C, C++]]></category> <category><![CDATA[switch]]></category> <category><![CDATA[variable]]></category><guid isPermaLink="false">http://www.kevinsubileau.fr/?p=822</guid> <description><![CDATA[En C++, il est possible de déclarer une nouvelle variable à tout moment dans le code... ou presque. Si vous déclarez une variable à l'intérieur d'un switch, il est possible que vous obteniez une erreur du compilateur ! <a href="http://www.kevinsubileau.fr/informatique/boite-a-code/c-cpp/cpp-declarer-variable-switch.html">Lire la Suite <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>En C++, il est possible de déclarer une nouvelle variable à tout moment dans le code... ou presque !</p><p>Ainsi, l'extrait de code ci-dessous est évidemment <strong>parfaitement valide</strong> et compile sans erreur :</p><pre class="gutter: true; brush: cpp; highlight: 3">for (int i = 0; i &lt; 10; ++i) {
    std::cout &lt;&lt; &quot;Itération n°&quot; &lt;&lt; i &lt;&lt; std::endl;
    int dummy;
    dummy = i * i;
    std::cout &lt;&lt; &quot;Le carré de &quot; &lt;&lt; i &lt;&lt; &quot; est &quot; &lt;&lt; dummy  &lt;&lt; std::endl;
}</pre><p>On note que <strong>la variable <code>dummy</code> est définie au milieu du code</strong>, sans que cela ne pose problème. Partant de ce constat, on pourrait croire que le code suivant compile également sans problème (en supposant que la variable <code>choix</code> est définie) :</p><pre class="gutter: true; brush: cpp; highlight: 4">switch (choix) {
    case 1:
        std::cout &lt;&lt; &quot;Choix 1.&quot; &lt;&lt; std::endl;
        int dummy = time(NULL); // Erreur !!
        std::cout &lt;&lt; &quot;Il est &quot; &lt;&lt; dummy &lt;&lt; std::endl;
        break;
    default:
        std::cout &lt;&lt; &quot;Choix inconnu.&quot; &lt;&lt; std::endl;
        // std::cout &lt;&lt; &quot;Il est &quot; &lt;&lt; dummy &lt;&lt; std::endl;
        break;
}</pre><p>Et bien non ! Si vous compiler un code de ce genre, <strong>le compilateur le refusera</strong> en indiquant une erreur du type :</p><pre class="brush: text; gutter: false;">error: jump to case label
   crosses initialization of &#039;int dummy&#039;</pre><p>ou encore, selon les cas :</p><pre class="brush: text; gutter: false;">error: initialization of &#039;dummy&#039; is skipped by &#039;case&#039; label</pre><p>La raison de cette erreur est que la <strong>portée</strong> de la variable définie à l'intérieur d'un <code>case</code> s'étend à l'ensemble du <code>switch</code>, et pas seulement à ce <code>case</code>. Le <code>case</code> n'est qu'un label, et ne limite pas la portée de la variable, qui n'est limitée que par les accolades englobantes du <code>switch</code>. Que se passerait il alors si le compilateur ne disait rien et que je décommentais la ligne 9 du code précédent ? Et bien, dans le cas où <code>choix</code> serait différent de 1, <strong>l'initialisation de la variable</strong> faite à la ligne 4 serait sautée puisque seul le bloc <code>default</code> serait exécuté. La variable <code>dummy</code> serait donc définie (puisque sa portée est globale à tout le <code>switch</code>) mais non initialisée (puisque l'initialisation n'a pas été exécutée). Dans cet exemple, <code>dummy</code> est un entier, il contiendrait simplement une valeur indéterminée. Mais ce pourrait tout aussi bien être un objet, et dans ce cas, <strong>le constructeur ne serait pas appelé</strong> si <code>choix</code> est différent de 1 ! Ce comportement risqué est donc interdit par le compilateur.</p><p>Pour résoudre ce problème, il faut explicitement limiter la portée de la variable en <strong>entourant le code du <code>case</code> par une paire d'accolades</strong>, comme ci-dessous :</p><pre class="gutter: true; brush: cpp; highlight: [3,5,8]">switch (choix) {
    case 1:
    {
        std::cout &lt;&lt; &quot;Choix 1.&quot; &lt;&lt; std::endl;
        int dummy = time(NULL); // Ok !!
        std::cout &lt;&lt; &quot;Il est &quot; &lt;&lt; dummy &lt;&lt; std::endl;
        break;
    }
    default:
        std::cout &lt;&lt; &quot;Choix inconnu.&quot; &lt;&lt; std::endl;
        // Désormais interdit car la variable est hors de portée !
        // std::cout &lt;&lt; &quot;Il est &quot; &lt;&lt; dummy &lt;&lt; std::endl;
        break;
}</pre><p>La portée de la variable <code>dummy</code> est ainsi limitée au <code>case</code>, et il devient <strong>impossible de l'utiliser dans un autre <code>case</code>.</strong></p><p>Voilà pour cette petite astuce de programmation en C++ assez simple, il suffit juste d'y penser ! A noter que ce problème et sa solution s'applique aussi lorsque l'on déclare une variable entre un <code>goto</code> et le label ciblé par ce <code>goto</code>. Mais bon, c'est bien connu, plus personne n'utilise le <code>goto</code> de nos jours...</p><p style="text-align: right;"><small><a href="http://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement">Source</a></small></p> ]]></content:encoded> <wfw:commentRss>http://www.kevinsubileau.fr/informatique/boite-a-code/c-cpp/cpp-declarer-variable-switch.html/feed</wfw:commentRss> <slash:comments>3</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching using disk: basic

Served from: www.kevinsubileau.fr @ 2026-04-22 21:08:51 -->