GCC vient de sortir sa version majeure annuelle, numérotée 6.1. Elle cumule les développements d’une année entière, avec des évolutions dans tous les domaines : côté C++, le compilateur se positionnera sur la norme C++14 par défaut, au lieu de C++98 auparavant, quelques fonctionnalités de C++17 ont été implémentées ; pour le domaine HPC, OpenMP 4.5 est complètement implémenté, les calculs peuvent être déportés sur des coprocesseurs Intel Xeon Phi « Knights Landing » et sur du matériel AMD par HSAIL ; l’implémentation de OpenACC 2.0a a été améliorée, avec une possible déportation sur du matériel NVIDIA par PTX. Au niveau matériel, les prochains processeurs d’AMD, basés sur l’architecture Zen, sont déjà pris en charge ; les plateformes ARM ont été le théâtre de bon nombre d’améliorations ; l’architecture PowerPC a reçu la compatibilité avec POWER9, la prochaine itération des processeurs d’IBM.Côté C++
La précédente version majeure de GCC, numérotée 5.1, apportait les dernières touches à l’implémentation de C++14, en apportant des fonctionnalités comme la désallocation d’une partie d’un tableau, des constexpr plus généraux, des fonctions anonymes génériques.
Cette nouvelle version de GCC s’arme déjà pour C++17, avec par exemple, la définition d’attributs sur les énumérateurs ou encore des expressions utilisant l’opérateur fold (aussi nommé reduce ou autre, selon les modes) :
| Code : | Sélectionner tout |
1 2 3 4 5 | // Cette fonction somme tous ses arguments.
template<typename... Args>
bool f(Args... args) {
return (true + ... + args);
} |
Plus de détails dans la documentation
Une nouvelle optimisation en C++ casse du code existant
Une nouvelle optimisation fait parler d’elle : la propagation de valeurs considère désormais que le pointeur this en C++ (qui pointe vers l’objet courant) est toujours initialisé (sa valeur n’est jamais nullptr). Ce point particulier n’a jamais été précisé dans une norme, les compilateurs sont donc libres quant à son interprétation — même si Qt 5 ou Chromium exploitaient l’implémentation précédente. Ce cas peut arriver pour des structures, comme un arbre binaire :
| Code : | Sélectionner tout |
1 2 3 4 | struct Node {
Node * left;
Node * right;
}; |
| Code : | Sélectionner tout |
1 2 3 4 5 | void in_order(Node* n) {
if (! n) return;
in_order(n->left);
in_order(n->right);
} |
| Code : | Sélectionner tout |
1 2 3 4 5 | void in_order() {
if (this == nullptr) return;
left->in_order();
right->in_order();
} |
Bien évidemment, une meilleure manière d'écrire le code vérifie directement chacun des deux pointeurs contenus dans la structure avant de continuer la récursion — ce qui évite en passant les problèmes potentiels avec cette optimisation :
| Code : | Sélectionner tout |
1 2 3 4 | void in_order() {
if (left) left->in_order();
if (right) right->in_order();
} |
Sources : GCC 6.1 Released, GCC 6 Release Series: Changes, New Features, and Fixes, C++ Standards Support in GCC.
Ce contenu a été publié dans C++, HPC et calcul scientifique par dourouc05.
Vous avez lu gratuitement 2 280 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
