34 votes

Pourquoi le lancement de 2 exceptions dans une ligne ne génère-t-il pas un avertissement de code inaccessible?

Pourquoi les lignes de code suivantes ne créent-elles pas un avertissement du compilateur?

 void Main()
{
  throw new Exception();
  throw new Exception();
}
 

À mon avis, le compilateur devrait vous informer que la deuxième exception de projection ne peut pas être atteinte.

38voto

Eric Lippert Points 300275

C'est clairement un bug du compilateur, et il a été introduit en C# 3.0 -- droit à l'époque que j'ai fortement remaniée, le vérificateur d'accessibilité. C'est probablement ma faute, désolé.

Le bug est totalement bénigne; fondamentalement, nous avons juste oublié un cas dans l'avertissement de journaliste. Nous générer de l'accessibilité de l'information correctement; comme d'autres l'ont noté, nous correctement couper les code inaccessible avant codegen.

Le bug n'est rien de plus qu'un manque de cas dans l'avertissement du générateur. Nous avons des problèmes de code qui nous permet de ne pas signaler un tas d'avertissements lorsque vous faites un peu de grande section de code inaccessible. Le compilateur a code pour plus spécifiquement les rapports des avertissements sur inconditionnelle gotos ("goto", "pause", "continuer"), à la condition gotos ("si", "si" et ainsi de suite), try-catch-finally (qui comprend l'équivalent de formes de try-catch-finally, comme le verrouillage et d'utilisation), des blocs, des rendements (taux de retour et le retour régulier), des déclarations locales, étiquetés états, de commutateurs et de l'expression des états.

Voyez-vous "jeter des déclarations" sur la liste? Moi non plus. C'est parce que nous l'avons oublié.

Toutes nos excuses pour la gêne occasionnée. Je vais envoyer une note à l'assurance qualité et nous allons obtenir un correctif pour résoudre ce dans une version future de la langue.

Merci pour avoir porté à mon attention.

7voto

Ash Points 951

Cela pourrait donner un avertissement / une erreur au compilateur, mais malheureusement ce n’est pas le cas. Mais si vous regardez le code IL, seule la première exception est considérée. Vous pouvez vous connecter à connect.microsoft.com et le définir comme quelque chose que vous aimeriez voir.

si vous utilisez le code ci-dessous

 static void Main(string[] args)
        {
            Console.Write("Line 1");
           throw new Exception(); 
           throw new Exception();
           Console.Write("Line 4");
        }
 

Vous obtiendrez ceci

 .method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       18 (0x12)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Line 1"
  IL_0006:  call       void [mscorlib]System.Console::Write(string)
  IL_000b:  nop
  IL_000c:  newobj     instance void [mscorlib]System.Exception::.ctor()
  IL_0011:  throw
} // end of method Program::Main
 

Après le premier objet Exception, rien d'autre n'est converti en IL.

3voto

Jeppe Stig Nielsen Points 17887

Ce bug (comme Lippert appelle ci-dessus) a d'étranges conséquences. Bien sûr, ce code donne également pas au moment de la compilation des avertissements:

static int Main()
{
  return 0;

  throw new Exception("Can you reach me?");
}

Si vous êtes créatif, vous pouvez toujours faire de l' throw déclaration induire (indépendantes) de mises en garde. Dans ce curieux exemple, le code génère un avertissement seulement parce que "vert" est inaccessible:

static int Main()
{
  return 0;

  throw new Exception(((Func<string>)(() => { if (2 == 2) { return "yellow"; } return "green"; }))());
}

(code crée une instance de délégué d'un lambda et invoque le délégué).

Mais cet exemple est plus simple et semble pire:

static int Main()
{
  int neverAssigned;

  return 0;

  throw new Exception(neverAssigned.ToString());
}

Ce dernier exemple de code compile également avec aucun avertissement! Il n'y a pas de problème dans "l'aide" neverAssigned parce que les "utilisation" est inaccessible. Mais vous pouvez également obtenir aucun avertissement à propos d'une variable locale ne jamais assigné (et jamais "vraiment" lire). Donc, pour reprendre, pas d'avertissement à tous, ce qui semble très mal.

Je me demande si ce comportement peut être modifié dans les prochaines versions de Visual C#? Changer il donnera aux gens avertissements qu'ils n'avaient pas auparavant (qui, à mon avis, ils méritent).

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