Comme je suis toujours occupé à 3000 trucs en même temps, il arrive que mes articles soient absolument sans liens avec les précédents. C’est le cas de celui-ci.

Je révise en ce moment C++, et pour bien l’utiliser il convient de réviser également l’utilisation du compilateur g++, lui-même issu de la suite GCC.

Je prends (plutôt volontairement) ce programme en exemple pour cet article :

#include <iostream>
using namespace std;

int main(int argc, char **argv) {
    cout << "Hello, you're on my blog :)" << endl;
    return(0);
}

Le programme le plus simpliste écrit en C++. Pour le compiler, le premier réflexe serait de faire tout simplement :

$ g++ code.cpp

Ce qui donnera un exécutable nommé a.out qui ne sera pas du tout optimisé. Vous me direz que pour ce qu’il y a dans ce code, on s’en fout, mais c’est un exemple. Imaginez ça sur un soft de millions de lignes de code.

g++ nous propose énormément de paramètres pour optimiser les exécutables générés, afficher des warnings en tout genre, bref : pour devenir de meilleurs humains en pissant du meilleur code. Voici les principaux que j’utilise.

  • -o : il permet de nommer l’exécutable issu de la compilation. g++ code.cpp -o code vous donnera un binaire code au lieu de a.out. Mignon, mais indispensable.
  • -Wall : active tous les warnings du compilateur.

Je m’arrête sur ce dernier cinq secondes. Tous ? Non. Malgré ce que son nom laisse suggérer, -Wall n’active pas tous les warnings possibles mais seulement les plus courants. Dans mon code, j’ai volontairement indiqué à la fonction main que j’allais utiliser des arguments, ce que je n’ai pas fait. Pourtant :

$ g++ code.cpp -o code -Wall
$ ./code 
Hello, you're on my blog :)

Aucun warning ! Ce qui m’amène à l’option des vrais perfectionnistes (n.m. : synonyme de masochiste en C++) : -Wextra. Une combinaison de -Wall et de -Wextra vous enverra à la gueule tous les warnings possibles sur votre code et vous permettra donc d'écrire un code (presque, j’y reviens juste après) irréprochable. Exemple sur notre code.cpp :

$ g++ code.cpp -o code -Wall -Wextra
code.cpp: In function ‘int main(int, char**)’:
code.cpp:4:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
    4 | int main(int argc, char **argv) {
      |          ~~~~^~~~
code.cpp:4:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
    4 | int main(int argc, char **argv) {
      |                    ~~~~~~~^~~~
$ ./code 
Hello, you're on my blog :)

La compilation passe (et l’exécution fonctionne) mais le compilateur nous dit en toute gentillesse:

MAIS PUTAIN TU FAIS QUOI BORDEL, TU DIS QUE TU VAS UTILISER DES ARGUMENTS ET TU NE LE FAIS PAS ! ALORS IL SERT À QUOI TON argc ET TON argv LÀ HEIN !!

Plus exactement, il indique que des paramètres sont déclarés mais non utilisés. On remarque d’ailleurs que -Wunused-parameter ne fait pas partie de -Wall. En tout cas, ce warning me permet alors d’optimiser mon code en :

#include <iostream>
using namespace std;

int main(void) {
    cout << "Hello, you're on my blog :)" << endl;
    return(0);
}

Et là, plus aucun warning à la compilation :

$ g++ code.cpp -o code -Wall -Wextra
$ ./code 
Hello, you're on my blog :)

J’ai dit que je reviendrais sur l’irréprochabilité (il faut rouler le “r” pour que ça soit optimal en bouche) du code, voici donc la petite mais non moins importante (last but not least, hein) option : -pedantic. Ça permet de corroborer le code avec la norme C++, et donc de vérifier qu’il est conforme en tout point à celle-ci. C’est le cas de mon code ici, mais ce n’est pas étonnant vu la simplicité de celui-ci.

$ g++ code.cpp -o code -Wall -Wextra -pedantic 
$ ./code 
Hello, you're on my blog :)

Les options de g++ sont tellement diverses et variées que certaines ne sont nécessaires que dans certains cas. Je vais donc finir sur les deux options supplémentaires que j’utilise le plus régulièrement (le but de cet article en fait).

  • -s : ce paramètre supprime toutes les informations de débogage de l’exécutable. C’est à double tranchant : il sera plus optimisé voire léger mais en revanche, il ne sera plus possible de le debugger avec gdb, par exemple. Je ne l’utilise donc que lors de la compilation finale, quand je suis certain d’avoir fini mon debug.
  • -O2 : pour optimiser la vitesse de l’exécutable. g++ propose trois niveaux d’optimisation, -O1, -O2 et -O3, du moins optimisé au plus rapide. Mais attention : les programmes générés seront en général de plus en plus lourds et, surtout (à prendre en compte lors de la compilation de mastodonte de code) la compilation devient de plus en plus longue au fur et à mesure que l’on monte dans les niveaux. C’est pour ça que -O2, c’est pas mal.

Conclusion : les paramètres que j’utilise en général, mais entres autres selon les cas (plusieurs fichiers sources, linking, etc, ), sont les suivants :

$ g++ code.cpp -o code -Wall -Wextra -O2 -s -pedantic

Si ça ne crache rien, ça veut dire que mon code n’est pas trop dégueu !