• [^] # Re: Comparaison ?

    Posté par (Mastodon) . En réponse au journal Journal Bookmark #2. Évalué à 4.

    Ce n'est pas de l'aveuglement, personne ne prétend que C++ est parfait, loin de là. Mais sur les exemples données, les erreurs sont facilement détectables, y compris à la compilation.

    Si je reprends certains des exemples :

    Sur le premier, clang me sort l'erreur suivante (en gras) :

    error: invalid operands to binary expression ('std::vector<int, std::allocator<int> >' and 'int')
     { return *__it == _M_value; }
    

    Je veux dire, c'est difficile d'être plus clair, on ne peut pas comparer un vector et un int.

    D'autant plus que son exemple C++ est moisi. Je propose plutôt ça comme exemple comparable :

    #include <algorithm>
    #include <vector>
    struct Foo {
     int i;
    };
    int main() {
     std::vector<Foo> foo;
     std::sort(foo.begin(), foo.end());
    }

    Et là, clang sort une erreur en gras :

    error: invalid operands to binary expression ('Foo' and 'Foo')
     { return *__it < __val; }
    

    Là, encore, c'est marqué, on ne peut pas comparer des Foo avec des Foo, bref comme Rust en gros. Et ces diagnostics vont s'améliorer dans la prochaine itération de C++ avec les concepts qui arrivent.

    Sur la variable non-initialisée, ça fait très longtemps que GCC renvoie des warnings. Et sur l'exemple en question, il renvoie :

    warning: ‘currmin’ may be used uninitialized in this function
    

    Bref, comme Rust.

    Sur l'exemple du switch, je trouve que c'est là qu'on atteint la mauvaise foi totale. Il ne respecte même pas la sémantique du langage. S'il faut un break, on met un break. Je ne vais pas décider dans mon coin tout seul que c'est con cette histoire de break et monter un exemple idiot comme ça où je montre que ce que je veux ne marche pas. Ben oui, ça pourrait difficilement être autrement. Surtout que son exemple provoque un warning :

    warning: enumeration value 'UNKNOWN' not handled in switch
    

    Sur l'exemple du for avec le point-virgule, pareil, on a un joli warning :

    warning: for loop has empty body
    

    Bref, dans ces quatre cas (sur dix), un compilateur C++ décent prévient l'utilisateur d'une erreur ou d'un risque d'erreur. Ça réduit son argumentation de 40%.

    Je pourrais parler du constructeur par copie implicite où, si on fait un code isomorphe à celui de Rust, on utilise unique_ptr ou shared_ptr et pas besoin d'implémenter quoi que ce soit hormis le constructeur, tous les trucs par défaut fonctionneront sans problème, avec une sémantique claire. Parce que là, le code en Rust, on a du mal à voir sa sémantique : ça compile, ça fonctionne sans erreur, mais qu'y a-t-il dans a et dans _b à la sortie, je ne saurais le dire.