Gcc

Un article de Haypo.

Retour à la page précédente Retour aux articles de programmation

gcc est le compilateur libre du projet GNU. Il supporte de nombreux langages (C, C++, Java, Pascal, Fortran, ...) et de nombreuses architectures (Intel, PowerPC, ARM, ...). On peut même compiler depuis un architecture vers une autre (compiler un programme Windows depuis Linux, ou bien compiler un programme pour ARM depuis un processeur Intel).

Sommaire

[modifier] Compiler un programme C

La syntaxe de base qui va créer un fichier "a.out" est :

gcc test.c

Mais je vous conseille de spécifier le nom du fichier de sortie et d'activer les avertissments. Ce qui donne une commande plus complète :

gcc test.c -o test -Wall -Wextra

Autres options du langage C :

  • -ansi : Limite le langage à la norme ANSI C
  • -pedantic : Encore plus restrictif que -ansi. En gros, si votre programme se compile avec -ansi, il se compile partout :-)

[modifier] Avertissements

  • -Wall : Cité plus haut, affiche un maximum d'avertissements. Permet souvent d'éviter des bugs.
  • -Wextra : Active plus d'avertissements que -Wall (pour gcc < 4.0, l'option s'appelait "-W" tout court)
  • -Werror : Les avertissements sont traités comme des erreurs.
  • -Wstrict-overflow
  • -Wconversion

Lire aussi warning options.

[modifier] Optimisation

gcc permet un grand nombre d'optimisations. Mais pour limiter le temps de compilation, il en limite grandement le nombre par défaut. Si vous voulez donc un programme ultra rapide, vous pouvez utiliser les options suivantes :

  • -O2 : Niveau d'optimisation moyen
  • -O3 : Active un maximum d'optimisations
  • -funroll-loops : Déroule les boucles
  • -ffast-math et -funsafe-math-optimizations : Se permet de réorganiser les opérations mathématiques sur les nombres flottants. Par défaut, gcc se l'interdit car cette opération peut produire des erreurs de calcul (comprendre, sur les chiffres après les virgules, on peut perdre en précision).
  • -finline-functions : Active la fonction d'« inline ». Ce mot anglais indique qu'une fonction ne vas pas être appelée, mais que son contenu va être recopié là où la fonction est appelée. Ceci n'est fait que la fonction est petite bien sûr.

Optimisations plus liées à l'architecture :

  • -march=athlon : Utilise le jeu d'instruction Athlon (ne se limite pas aux instructions basiques du Pentium). Il existe encore les architectures i686, pentium2, pentium3, pentium4, opteron, ...
  • -mmmx, -msse, -msse2, -msse3, -m3dnow : Active les extensions des processeurs Intel et AMD
  • -mfpmath=sse : Utilise l'unité SSE pour les calculs en nombre flottant
  • -fstrict-aliasing : Aligne de manière stricte les variables en mémoire. Le programme aura une empreinte mémoire plus importante. Par contre, il faut savoir que c'est lourd pour le processeur de lire une variable qui n'est pas bien aligné (il est obligé de faire deux accès mémoire pour lire une seule variable !).

Autre :

  • -Os : Au contraire, cette option indique qu'on ne s'inquiète pas de la vitesse d'exécution, mais qu'on préfère le programme le plus petit possible !
  • -fwrapv : Indique au compilateur qu'un dépassement de capacité en arithmétique signée (addition, soustraction, multiplication) boucle en utilisant la représentation par complément de deux. Cette option désactive certains optimisations.
    • « x = a + C1 + b + C2 + c » (où C1 et C2 sont des constantes) est optimisé « x = a + b + c + C3 » (C3 = C1 + C2) sans fwrapv. Avec l'option, l'expression est inchangée car la nouvelle expression peut amener un dépassement de capacité que l'expression originelle n'a pas.
    • Le test « (offset + len) < 0 » est considéré comme toujours vrai sans -fwrapv
    • Demande d'ajout de -fwrapv pour le noyau Linux : Kernel should be built with -fwrapv

[modifier] Sécurité

[modifier] Options pour le débogueur

  • -O0 : Désactive toutes les optimisations, permet de compiler plus vite
  • -g : Ajoute des informations de débogage pour permettre l'utilisation du débogueur par défaut sur votre système (gdb sous Linux par exemple)

[modifier] Extensions de gcc

gcc permet d'utiliser des extensions, standards ou non, dans vos programmes.

[modifier] Les attributs (__attribute__)

Bon, je n'ai jamais utilisé ça, mais je le met quand même car ça peut servir.

  • aligned : Permet de spécifier manuellement comment les variables sont alignées
 struct S { short f[3]; } __attribute__ ((aligned (8)));
  • deprecated : Indique qu'un type/variable/fonction est déconseillé, et qu'il/elle va bientôt être supprimé. Utile dans une librairie pour garder la compabilité avec la version précédente, mais en indiquant qu'il faut changer le code pour être sûr que le programme compilera avec la prochaine version.
 typedef int T1 __attribute__ ((deprecated));
  • pure : fonction qui ne modifie aucune variable globale (mais peut lire une variable globale)
    • const : (encore plus stricte que pure) fonction n'utilisant aucune variable globale (ni en lecture, ni en écriture)
  • warn_unused_result : avertissement si le retour d'une fonction n'est pas utilisé
  • __used__/__unused__ : indique que l'argument d'une fonction est/n'est pas utilisé
  • always_inline : inline toujours la fonction
  • deprecated : gcc affiche un avertissement "deprecated" si la variable/fonction est utilisée
  • constructor : fonction appelée avant le début du programme (fonction main())
  • destructor : fonction appelée à la sortie du programme (exit())
  • signal : indique que la fonction est un handler de signal => les signaux sont désactivés à l'entrée de cette fonction (et réactivés après)

Autres attributs :

  • (vu dans le noyau Linux) nocast et « noderef, address_space(n) », __context__, force, safe
  • fastcall
  • noreturn
  • nonnull (arg-index, ...)
  • returns_twice
  • visibility

[modifier] Type long long

On peut utiliser le type "long long" qui fait 64 bits (qu'importe qu'on soit sur une architecture 32 ou 64 bits).

Ce n'est une extension, cela fait parti de la norme ANSI C99. Malheureusement, peu de compilateurs gèrent la norme C99.

Note: Pour déclarer une constante long long, il faut utiliser le suffixe "LL" (ou "ULL" pour les nombres non-signés). Exemple :

 const long long seizezeros = 10000000000000000LL;

[modifier] Fonctions builtin

  • __builtin_offsetof(a,b) : offset en octet d'un attribut dans une structure
  • __builtin_expect(x, y) : indique que la valeur x aura le plus souvent la valeur y. Cette fonction aide gcc pour la prédiction de branche et est donc utilisé avec un test (ici on indique que les erreurs sont très rares) :
if (__builtin_expect(has_error, 0))
   error();
no_error();
...

[modifier] Profiling

Le profiling (mot anglais) permet de mesurer un plus juste le temps passé dans chaque portion de code. Ceci est très utile pour savoir quelle partie d'un programme doit être optimisée (pour rappel, en général, il y a seulement 20% du code qui utilise 80% du temps CPU). On peut connaître le nombre d'appel à une fonction donnée, et le temps total passé dans telle ou telle fonction.

Il faut utiliser un programme tel que gprof pour analyser les mesures.

L'option gcc en question est « -pg ».

[modifier] Gcc et l'assembleur

On peut utiliser de l'assembleur dans un programme C avec l'instruction asm. Exemple :

 asm ("fsinx %1,%0" : "=f" (result) : "f" (angle));

(calcule le sinus d'un angle)

C'est très pratique car on utilise directement nos variables C en assembleur, c'est transparent pour le programmeur.

[modifier] Voir aussi

[modifier] Articles connexes

[modifier] Liens externes