C++17
Parmi les nouveautés concernant C++, on peut noter une gestion expérimentale de l’entièreté de la norme C++17. Il faut encore l’activer manuellement lors de la compilation (avec l’option -std=c++1z), au moins jusqu’à la publication de la version finale de la norme. Les progrès par rapport à GCC 6 sont notables, comme montré dans le tableau ci-dessous. Néanmoins, la bibliothèque standard n’est pas encore à ce niveau d’implémentation.
[[fallthrough]] attribute | P0188R1 | __has_cpp_attribute(fallthrough) |
Extension to aggregate initialization | P0017R1 | __cpp_aggregate_bases >= 201603 |
Wording for constexpr lambda | P0170R1 | __cpp_constexpr >= 201603 |
Lambda capture of *this by Value | P0018R3 | __cpp_capture_star_this >= 201603 |
Construction Rules for enum class variables | P0138R2 | |
Dynamic memory allocation for over-aligned data | P0035R4 | __cpp_aligned_new >= 201606 |
Guaranteed copy elision | P0135R1 | |
Refining Expression Evaluation Order for Idiomatic C++ | P0145R3 | |
constexpr if | P0292R2 | __cpp_if_constexpr >= 201606 |
Selection statements with initializer | P0305R1 | |
Template argument deduction for class templates | P0091R3 | __cpp_deduction_guides >= 201606 |
Declaring non-type template parameters with auto | P0127R2 | __cpp_template_auto >= 201606 |
Using attribute namespaces without repetition | P0028R4 | |
Structured bindings | P0217R3 | __cpp_structured_bindings >= 201606 |
Remove Deprecated Use of the register Keyword | P0001R1 | |
Remove Deprecated operator++(bool) | P0002R1 | |
Make exception specifications be part of the type system | P0012R1 | __cpp_noexcept_function_type >= 201510 |
Rewording inheriting constructors (core issue 1941 et al) | P0136R1 | __cpp_inheriting_constructors >= 201511 |
Inline variables | P0386R2 | __cpp_inline_variables >= 201606 |
DR 150, Matching of template template arguments | P0522R0 | __cpp_template_template_args >= 201611 |
Removing dynamic exception specifications | P0003R5 | |
Pack expansions in using-declarations | P0195R2 | __cpp_variadic_using >= 201611 |
A byte type definition | P0298R0 |
Diagnostics C et C++
Les diagnostics pour le code C et C++ ont été encore largement améliorés : GCC 6 apportait bon nombre d’améliorations, cette nouvelle itération continue le travail. Principalement, le compilateur propose des corrections pour les fautes de frappe, que ce soit des membres de structures, des fonctions, des macros, des énumérations ou des types.
Code : | Sélectionner tout |
1 2 3 4 | spellcheck-fields.cc:52:13: error: 'struct s' has no member named 'colour'; did you mean 'color'? return ptr->colour; ^~~~~~ color |
Code : | Sélectionner tout |
1 2 3 4 | test.c:5:2: error: invalid preprocessing directive #endfi; did you mean #endif? #endfi ^~~~~ endif |
Code : | Sélectionner tout |
1 2 3 4 | test.c:51:29: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'int' [-Wformat=] printf ("foo: %d bar: %s baz: %d", 100, i + j, 102); ~^ ~~~~~ %d |
Code : | Sélectionner tout |
1 2 3 4 | test.cc:4:11: error: expected ';' after class definition class a {} ^ ; |
Au niveau de la sécurité, bon nombre de nouveaux messages permettent de détecter les risques de dépassement de capacité et d’autres formes d’accès invalides à la mémoire. Par exemple, des appels à malloc() avec une taille de mémoire négative donne un avertissement :
Code : | Sélectionner tout |
1 2 3 4 5 6 | void* f (int n) { return malloc (n > 0 ? 0 : n); } warning: argument 1 range [2147483648, 4294967295] exceeds maximum object size 2147483647 [-Walloc-size-larger-than=] |
De même, certaines failles potentielles lors de l’utilisation de fonctions de la famille printf sont détectées :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | void* f (int mday) { char *buf = malloc (3); sprintf (buf, "%02i", mday % 100); return buf; } warning: 'sprintf may write a terminating nul past the end of the destination [-Wformat-overflow=] note: 'sprintf' output between 3 and 4 bytes into a destination of size 3 |
GCC 7 apporte bon nombre de nouvelles passes d’optimisation du code. Par exemple, certains appels à sprintf peuvent être remplacés par des constantes, la taille de leur sortie peut être estimée (avec des bornes supérieures et inférieures). Les opérations d’écriture en mémoire sont rassemblées, afin d’effectuer moins d’instructions, chacune copiant plus de données.
Les passes interprocédurales peuvent analyser les bits des variables forcément à zéro (ce qui inclut l’alignement des pointeurs, déjà disponible avec GCC 6) et donner l’information aux autres passes. Pour les variables entières, les bornes sur les valeurs sont transmises aux autres algorithmes d’optimisation.
Certaines boucles ont la particularité d’avoir une condition toujours vraie pour une partie des itérations puis fausse pour les suivantes. Dans ce cas, GCC 7 peut séparer la boucle en deux parties, de telle sorte que la condition ne doit plus être vérifiée.
Calcul de haute performance
OpenMP est une série d’annotations pour le code C, C++ et Fortran qui indique au compilateur comment le paralléliser. GCC 6 implémentait la version 4.5 de la norme pour C et C++, GCC 7 l’apporte à Fortran, avec l’exception de la correspondance des éléments de structure.
GCC peut maintenant produire des exécutables au format BRIG 1.0. Il est utilisé dans le cadre de la plateforme AMD HSA. L’objectif est de déporter facilement du code OpenMP sur n’importe quel type d’accélérateur, comme un GPU, ce qui est défini depuis OpenMP 4.
NVIDIA n’est pas en reste, GCC peut maintenant produire des binaires au format NVPTX, utilisé sur les cartes graphiques de la marque. Cet export est utilisé pour décharger l’exécution de code OpenMP.
Autres langages
GCJ, le compilateur Java, n’était plus vraiment maintenu depuis des années, il est maintenant supprimé. Le compilateur Go est mis à jour pour la version 1.8 du langage.
Sources : GCC 7 Release Series, C++ Standards Support in GCC, libstdc++ Implementation Status.