• [^] # Re: En vrac

    Posté par . En réponse au journal Pourquoi empaqueter KDE prend-il du temps ?. Évalué à 4. Dernière modification le 21 août 2014 à 19:14.

    Tout structure de contrôle est un GOTO caché que ce soit le if, le while ou le for par exemple.

    Je ne suis pas d'accord pour dire ça comme ça. Au niveau assembleur, un goto est bien entendu un branchement inconditionnel, et peut viser une adresse arbitraire (jmp <ADRESSE_ARBITRAIRE>). La seule sémantique de goto est de se brancher là où on lui dit. La sémantique du if est celle d'un branchement conditionnel, qui va à une adresse relative (jne <DÉPLACEMENT_RELATIF>). Les structures de boucle while et for font appel à un branchement conditionnel et un branchement inconditionnel. On part de :

    while ( condition ) {
     corps;
    }
    apres_la_boucle;

    On arrive à quelque chose de ce genre (avec une « traduction » asm naïve) :

    BOUCLE:
    if (!condition) goto APRES_LA_BOUCLE; // par exemple: jge APRES_LA_BOUCLE
    corps;
    goto BOUCLE; // jmp BOUCLE
    APRES_LA_BOUCLE:
    apres_la_boucle;

    Mais il y a une sémantique très spécifique qui limite où le saut peut s'effectuer (si tu veux, on pourrait dire qu'un if ou une boucle ont certes une étiquette implicite, mais on sait exactement où elle est placée). Avec des branchements inconditionnels « relatifs », de type break ou continue, c'est la même chose: dans le cas du break on effectuera un jmp APRÈS_LA_BOUCLE et dans le cas d'un continue ce sera jmp BOUCLE, mais tout est confiné correctement. Dans tous les cas, tu as la garantie que tu ne peux pas atterrir dans une portion de code arbitrairement, comme par exemple:

    int a = 0;
    void foo(int n) {
     if (n == 0) goto LABEL; // wah trop bien hé, t'as vu l'optim' ?
     // reste du code...
    }
    // plein de fonctions entre les deux
    int bar(void) {
    LABEL:
     ++a;
    }

    Les exceptions sont quelque chose d'intermédiaire entre le goto et les branchements conditionnels selon moi: elles ressemblent à une forme de « gotos typés ». Exactement comme avec un goto, il faut spécifier des labels à des endroits précis (grâce à la construction try { ... } catch(...)). Contrairement à un goto, il y a un minimum de maîtrise sur où le saut peut arriver (car try/catch est bien une structure de contrôle), mais les sauts peuvent être bien plus longs que la portée lexicale d'un bloc (comme c'est le cas pour if/while/for/break/continue).

    Ce qui pose problème ce n'est pas les exceptions, c'est la gestion des exceptions par le C++. En Java le fait d'obliger à déclarer les exceptions qu'une méthode lève (mis à par les RuntimeException) réduit de beaucoup le problème de lecture du flow d’exécution

    Ça par contre je suis tout à fait d'accord : forcer à déclarer quelles exceptions peuvent être levées permet au compilateur d'engueuler le programmeur qui spécifie des « étiquettes » n'importe comment, et de préciser s'il veut traiter une exception ou non.

    Ça n'empêche pas qu'il est parfaitement possible d'utiliser les exceptions non pas comme un mécanisme de gestion d'erreurs, mais comme un mécanisme de « goto contrôlé ».