28 votes

Pourquoi le compilateur se plaint-il que «tous les chemins de code ne renvoient pas de valeur» alors que je peux clairement voir qu'ils le font?

Je suis à essayer de comprendre pourquoi le compilateur a un problème avec cette fonction. Il me donne le "Pas tous les chemins de code renvoie une valeur d'erreur", cependant je ne peux pas voir une situation où les flux de contrôle passerait à l' if( a ) expression sans a être vrai (si l' if( a ) est superflu, mais le compilateur ne semble pas reconnaître que).

public static Boolean Foo(Boolean x)
{
    Boolean a = false;
    if( x )
    {
        a = true;
    }
    else
    {
        try
        {
            SomethingThatMightThrow();
            Assert.IsFalse( a );
            return a;
        }
        catch(Exception)
        {
            a = true;
        }
    }

    if( a )
    {
        return x;
    }
}

La solution immédiate est de tout simplement supprimer l' if( a ) garde déclaration complètement et juste return x immédiatement - mais pourquoi ne le compilateur se plaindre, même si elle devrait être en mesure de prouver de manière statique tous les chemins de code possible de tirer une return déclaration? Surtout, il n'y a pas de boucles, qui sont souvent la raison principale de l'échec de prouver return-ness.

Je suis en utilisant VS2015 mise à Jour 3.

26voto

John Wu Points 2633

Il s'agit de l'exécution par rapport à la compilation

Votre exemple est beaucoup trop compliqué. Cela ne compilera pas non plus:

 static int Test()
{
    bool f = true;
    if (f)
    {
        return 1;
    }
    else
    {
        //Not all code paths return a value
    }
}
 

D'un autre côté, cela:

 static int Test()
{
    if (true)
    {
        return 1;
    }
    else
    {
        //No error
    }
}
 

Je suppose que quels que soient les mécanismes de validation en place, ils n'ont pas une logique suffisante pour déduire le contenu d'une variable d'exécution. Les variables de compilation ne posent aucun problème.

6voto

Alexei Points 3124

Je pense que le compilateur est très simple analyse sur le code et donc le retour doit être explicite.

Cela pourrait ressembler à une mauvaise décision, mais lorsque l'on traite avec un code complexe, la valeur de retour peut ne pas être clair. Ainsi, le programmeur est obligé de revenir à elle.

Votre exemple peut être réduite à un minimum, comme ceci:

public static Int32 Main(String[] args)
{
    var printUsage = true;
    if (printUsage)
    {
        return 0;
    }

    // return nothing, so compiler is not happy
}

tout en continuant de l'erreur.

REMARQUE: si vous utilisez Resharper, il va effectuer l'analyse que vous voulez et vous avertir en conséquence:

if (printUsage)         // Warning: expression is always true 

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