2017-03-01 2 views
4

Je veux savoir s'il y a moyen pour le compilateur de comprendre que deux instructions if ne peuvent pas être vraies en même temps, et d'ajouter un "implicite else". Par exemple, dans cet exemple de code:optimisation du compilateur implicite else

int main() { 
    char c; 
    scanf_s("%c", &c, 1); 
    if (c == '1') { 
     printf("received 1\n"); 
    } 

    if (c == '2') { 
     printf("received 2\n"); 
    } 

    return 0; 
} 

c ne peut pas être '1'et'2', mais après la compilation dans Visual Studio et désassemblage j'ai remarqué qu'il vérifiera la deuxième if, peu importe quoi.

+1

Vérifiez une version de version. –

+2

Quelle réponse attendez-vous, en plus de * "c'est possible, mais cela dépend du compilateur" *? – user694733

+0

@BaummitAugen J'ai vérifié la version finale. – yeger

Répondre

0

Je vais répondre dans le contexte de LLVM/CLANG parce que je connais peu ses internes.

Si vous activez l'optimisation mem2reg dans opt, elle traitera c comme une variable temporaire plutôt que comme une variable sur la pile (dans les phases avant l'allocation du registre).

Là l'optimiseur peut faire l'hypothèse exigée et dans ce cas dire le deuxième si était dans le premier, il serait enlevé par DCE.

Mais je ne peux pas penser à un passage de la suite LLVM qui ajouterait un "elseif".

La même chose ne peut pas être dit à propos d'autres compilateurs comme gcc/msvc.

0

Est-ce qu'un compilateur théoriquement peut effectuer l'optimisation que vous suggérez? Oui, c'est absolument possible, mais en s'assurant que l'analyse sémantique requise pour détecter de tels scénarios dans le compilateur est absolument non-trivial, et la question est de savoir si l'effort de développement ne pourrait pas être mieux dépensé ailleurs.

1

Je veux savoir s'il existe un moyen pour le compilateur de comprendre que deux instructions if ne peuvent pas être vraies en même temps, et d'ajouter un "implicit else".

Oui, il y a: le compilateur Intel C icc 17 fait, comme on peut le vérifier avec Matt Godbolt's Compiler Explorer, mais ni clang ni gcc semblent effectuer cette optimisation.

0

Puisque scanf_s() est donné un pointeur vers la variable c cette variable ne peut plus être considérée comme une variable locale. A priori, la fonction pourrait stocker ce pointeur quelque part et toutes les autres fonctions (inconnues du compilateur) pourraient stocker quelque chose via ce pointeur, comme par exemple l'appel à printf("received 1\n"). En d'autres termes, le compilateur ne peut effectuer cette optimisation sans connaître les fonctions de la fonction scanf_s() et printf().