La conception de C++ 20 est achevée et le premier brouillon sera publié en juillet 2019,
Les Modules et les Coroutines y sont présents

Le , par Bill Fassinou

210PARTAGES

20  0 
La toute dernière réunion du comité ISO C++ pour approuver les nouvelles fonctionnalités à venir dans C++ 20 s’est tenu la semaine passée à Kona, à Hawaii. À l’issu de cette réunion, le comité a annoncé que les fonctionnalités du prochain standard international (SI) du langage de programmation C++, le C++ 20 sont maintenant finalisées. Il a également indiqué qu’une prochaine réunion, prévue pour juillet prochain, mettra fin à la spécification et verra la publication d’un brouillon pour examen. Le président du comité de normalisation ISO C++, Herb Sutter, (également auteur, conférencier et architecte logiciel chez Microsoft) a déclaré ce qui suit : « Nous connaissons ainsi la plupart des fonctionnalités finales de C++ 20 ! Lors de notre prochaine réunion en juillet, nous prévoyons d’adopter officiellement quelques fonctionnalités supplémentaires qui ont été approuvées par la conception lors de cette réunion, mais qui n’ont pas encore été révisées dans leur intégralité. À la fin de la réunion de juillet, nous lancerons ensuite le premier bulletin de commentaires pour C++ 20 pour d’examen ».

Parmi les nombreuses nouvelles fonctionnalités approuvées pour le C++ 20, deux fonctionnalités majeures sont à noter. Il s’agit des fonctionnalités dénommées Modules et celles dénommées Coroutines. Comme l’explique Herb Sutter, les Modules constituent une nouvelle alternative aux fichiers d’en-tête et apportent un certain nombre d’améliorations clés notamment en isolant les effets des macros et en permettant des générations évolutives. Cette fonctionnalité permet aux utilisateurs du langage de définir une limite d’encapsulation nommée, une première depuis ses 35 ans d’âge selon Sutter. Il existait jusque-là trois fonctionnalités de ce type qui permettent aux programmeurs de créer leurs propres mots de pouvoir en (a) donnant un nom défini par l'utilisateur en (b) quelque chose dont l'implémentation est cachée, explique Sutter. Ce sont : la variable (qui encapsule la valeur actuelle), la fonction (qui encapsule le code et le comportement) et la classe (qui encapsule les deux pour délivrer un ensemble d’états et de fonctions).

Même des fonctionnalités majeures telles que les Modèles constituent des moyens de décorer ou de paramétrer ces trois fonctionnalités fondamentales. À ces trois, est ajoutée maintenant une quatrième, les Modules qui encapsulent les trois pour en livrer un ensemble. Les Coroutines quant à eux, sont des fonctions qui peuvent suspendre et reprendre leur exécution tout en conservant leur état. L'évolution en C++ 20 va encore plus loin. Le terme Coroutines est inventé par Melvin Conway, un informaticien. Il l'a utilisé dans sa publication pour la construction d'un compilateur en 1963. Cette fonctionnalité existe également dans les langages comme Python. L'implémentation spécifique de Coroutines en C++ est un peu intéressant. Au niveau le plus élémentaire, il ajoute quelques mots-clés à C++ comme co_return, co_await, co_yield ainsi que des types de bibliothèques qui fonctionnent avec eux. Une fonction devient une coroutine en ayant une de ces fonctions dans son corps.


Lorsqu'un de ces trois mots-clés est utilisé dans un corps de fonction, un examen standard obligatoire du type de retour et des arguments est produit et la fonction est transformée en une coroutine. Cet examen indique au compilateur où stocker l'état de la fonction lorsque celle-ci est suspendue. La spécification s’est portée également sur d’autres fonctionnalités et modifications telles que :

  • l’extension des liaisons structurées et la capture de référence des liaisons structurées qui permettent à un nom introduit en tant que liaison structurée d'être utilisé de manière supplémentaire, par exemple d’être capturé par référence dans des lambdas ;
  • &#8660;! === qui ajoute une meilleure prise en charge linguistique pour la composabilité lors de l'écriture <=> pour les types pouvant écrire un == plus efficace que d'utiliser l'opérateur <=> seul. Par exemple, le vecteur <T> peut court-circuiter la comparaison == en vérifiant d’abord si les deux vecteurs ont la même taille ;
  • changer span pour utiliser une taille non signée et ajouter des fonctions ssize() pour obtenir les tailles signées. Cette fonctionnalité rend std::span plus pratique à utiliser avec les types STL existants, tout en permettant l’utilisation de tailles et d’index signés via ssize( ) pour bénéficier des avantages de la signature ;
  • le polymorphic allocator. Il permet à pmr::memory_resource d'être utilisée partout où des allocateurs peuvent être utilisés dans la bibliothèque standard ;
  • etc.

Le comité à travers le reportage de Sutter, a indiqué que les processus tels que les exécuteurs et la mise en réseau continuent de progresser, les deux étant étroitement liés. « Nous espérions qu'une partie des exécuteurs serait prête pour le C++ 20, mais ils n'ont pas réussi la coupe. Ils sont tous deux sur la bonne voie pour bientôt, post C++ 20 (c'est-à-dire au début de la phase C++ 23) », a expliqué Herb Sutter, le président du comité. Beaucoup félicitent l’effort mis en œuvre par le comité pour offrir ces nouvelles fonctionnalités à la communauté C++ et l’encouragent à faire encore plus pour la prochaine standardisation du langage (C++ 23).

Cependant, certains expriment leur mécontentement par rapport au fait que la mise en réseau soit encore laissée de côté comme il a été le cas plusieurs fois déjà. Néanmoins, pour l’effort qui est fait, plusieurs y voient une expérience très excitante et encouragent à une adoption à grande échelle du C++ 20. Les autres fonctionnalités telles que les Concepts, les Ranges, les Contrats qui avaient été introduites dans C++ 20 avant cette réunion sont présentées et expliquées sur le site de l’ISO C++. Vous y retrouverez également d’autres annonces ainsi que le calendrier des autres événements à venir pour livrer complètement le C++ 20.

Source : Billet de blog

Et vous ?

Que pensez-vous de ces nouveautés de C++ 20 ?

Voir aussi

De C++14 à C++17, qu'est-ce qui a changé avec la nouvelle version du langage C++ : un document de la Standard C++ Foundation

La spécification de la nouvelle version du langage C++ (C++17) est finalisée quelles sont les nouveautés introduites ?

Le premier brouillon de la prochaine révision du standard C, le C2x, est publié et met l'accent sur la compatibilité du langage

Internet aurait de sérieux problèmes à cause de langages comme C et C++ favorisant la survenue de failles mais peu de développeurs s'en soucieraient

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de Pyramidev
Expert confirmé https://www.developpez.com
Le 26/02/2019 à 20:18
Citation Envoyé par Mingolito Voir le message
C'est pas mal, mais bon le C++ est très en retard est encore très loin de pouvoir rattraper l'énorme avance du C# qui est bien plus moderne et surtout bien mieux foutu, le C++ reste un langage désuet et ringard.

D'ailleurs l'avenir c'est clairement le langage Julia qui n'a que des avantages
Comparé aux autres langages connus de haut niveau comme Java et C#, C++ est en retard sur certains points, mais il est en avance sur d'autres, surtout quand on a besoin d'avoir de bonnes performances.

Du côté des langages émergents, peut-être que Julia s'imposera dans les applis qui n'auront pas besoin de performances aussi élevées qu'avec du C++ optimisé. Mais, tant que Julia nécessitera d'utiliser un ramasse-miettes, il ne sera pas un vrai concurrent du C++. Le futur concurrent le plus sérieux du C++ me semble être Rust.
9  0 
Avatar de ParseCoder
Membre averti https://www.developpez.com
Le 26/02/2019 à 0:12
C'est une version bien pleine, très intéressante et ça promet du boulot pour maîtriser tout ça. Voilà la liste des nouveautés dans le post de Herb Sutter (en plus il précise "modulo any additional features in July":

modules
coroutines
concepts
contracts
<=> spaceship
“lots more constexpr”: broad use of normal C++ for direct compile-time programming, without resorting to template metaprogramming (see last trip report)
ranges
calendars and time zones
span
and lots more

Il a raison de dire:
Citation Envoyé par Herb Sutter
We understand that’s exciting, but we also understand that’s a lot for the community to absorb
7  0 
Avatar de Aurelien.Regat-Barrel
Expert éminent sénior https://www.developpez.com
Le 08/03/2019 à 1:31
Citation Envoyé par stardeath Voir le message
donnez moi un exemple concret de truc, qui fonctionnerait correctement avec le c++ tel que le comité l'a designé actuellement et qui ne fonctionnerait pas avec mon modèle.
Pour moi le modèle que tu proposes ne concerne pas le langage mais le build système : tu peux très bien le mettre en place à l'heure actuelle avec cmake ou outil équivalent. C'est à ce genre d'outil qu'incombe la gestion de versions et autres options de compilation par fichier, pas au langage. Mais si tu tiens absolument à gérer ça dans le code, c'est techniquement possible depuis longtemps via le préprocesseur, et c'est plus un truc qu'on fait quand on a vraiment pas le choix (période de transition) car c'est très dommageable pour la lisibilité du code.

Ensuite, de mon point de vue, le modèle idéal que tu as en tête comporte de grosses lacunes qui ne manqueront pas de rapidement se retourner contre toi si tu imposes ça dans une grosse équipe : ça va être le défilé de critiques envers toi, dont certaines qui peuvent potentiellement être très agressives car tu empêches des gens de travailler. Pourquoi ?

Tout simplement parce qu'un code écrit dans une vielle version du langage et un autre dans une version récente, dans la vraie vie, ça n'existe pas. Le nouveau code se greffe par dessus l'ancien : ça commence par un fichier de 2000 lignes écrits en C++98, puis on ajoute/modifie 1000 lignes en C++11, 500 en C++14, 200 en C++17 au fil des années. Et ce que tu veux absolument éviter c'est :
- figer un code dans une version précise de C++ : cela condamne ton code à la mort et te met en danger vis à vis de ton écosystème qui va cesser de supporter cette version à un moment donné (lib tierces...)
- devoir mettre à niveau 2000 lignes de C++98 (avec impact sur le code qui en dépend...) avant de pouvoir rajouter une seule ligne plus moderne dans un fichier existant

Aussi, techniquement parlant, passé un certaine taille / un certain nombre de dépendances, il est risqué voire impossible de mélanger du code compilé dans des modes différents (l'ABI de C++ n'est pas stable). Pour rappel les types aussi courant que std::string changent d'une version de compilo à l'autre et ne peuvent donc pas être mélangées. Qui plus est, recompiler son vieux code en mode récent apporte des gains de perf qui peuvent être significatifs (la move semantic dans la STL a d'ailleurs été conçue pour ça: augmenter les perfs de ton code legacy sans avoir à le retoucher).

Typiquement, chaque gros projet va avoir quelques fichiers qui centralisent une grosse partie de l'application et dépassent l'entendement en terme de lignes de code (par exemple, le fichier qui contient le code de la fenêtre principale d'une GUI). Et assez logiquement, ce sont des fichiers qui bougent beaucoup vu que c'est là que tout le code de l'application converge. J'ai bossé sur un projet (3M de LOC) où ce genre de fichier dépasse les 30.000 LOC (200 lignes d'include...). Ce fichier reçoit une dizaine de commits par semaine (+60 développeurs). Si tu imposes C++98 sur ce fichier qui est tout en bas du graphe de dépendances (un des tout premier fichier de l'application ville de 15 ans!), tu imposes C++98 sur tous les autres fichiers et modules qui sont inclus (c'est à dire les 3/4 de l'application). A l'inverse, si tu imposes un niveau de qualité moderne sur ce fichier vieux de 15 ans, eh bien, explique à ton manage que tu ne vas plus rien produire d'autre que des régressions pour l'année qui vient.

C'est ça le legacy : un mélange de styles et de versions dans un même fichier. Il y a des parties qu'on fait évoluer quand le besoin s'en fait ressentir, et le reste, on n'y touche pas. Et c'est valable dans tous les autres langages : on ne compile par telle méthode en Php 4 et telle autre en Php 7.

La gestion des versions est quelque chose qui ne relève pas du langage mais de la méthodologie de travail. Ca se gère avec des outils adaptés (build système, package manager...), des processus rigoureux (automatisation complète de toute sa toolchain, traçabilité des 3rd parties...) et de la formation/communication interne. Et ça a finalement assez peu à voir avec le langage utilisé.

La position du comité C++ est d'encourager la migration automatique de code vers les normes les plus récentes. Du coup C++ dispose depuis des années d'un tel outil, efficace et gratuit. Tous les autres langages ne peuvent pas en dire autant.

Un dernier point est que l’adoption par l'industrie des nouvelles normes C++ est très rapide. Là encore tous les langages popuilaires ne peuvent pas en dire autant (python...). Certains langages se sont même bien vautré là dessus (perl...). C'est un élément factuel qui montre que le comité de normalisation C++, dans l'ensemble, et compte tenu des énormes défis soulevés, fait du bon travail. Après les critiques constructives sont les bienvenues sur leur liste de discussion.
7  0 
Avatar de gl
Rédacteur https://www.developpez.com
Le 01/03/2019 à 7:12
Citation Envoyé par stardeath Voir le message
les excuses habituelles de la rétrocompatibilité et de faire évoluer son code ne tiennent pas une seule seconde.
Pourquoi ?

Je ne vois pas comment on pourrais se passer, au moins à court terme (et donc sur une ou deux versions successives), de rétrocompatibilité. Et donc il n'est pas anormal de continuer à supporter des syntaxes anciennes bien que gênantes.

Citation Envoyé par stardeath Voir le message
qu'est ce qui est passé par la tête du comité pour se dire que par exemple ça : virtual int foo() override
c'est acceptable niveau syntaxe? (et ça c'est encore gentillet comme exemple de stupidité)
Autant je suis d'accord qu'il existe des syntaxes qui, au moins en partant d'une feuille blanche, pourrait être grandement améliorer, autant ici je ne vois pas vraiment de souci. Sachant en outre que le virtual est ici inutile et que le code effectivement écrit serait plus certainement int foo() override
6  0 
Avatar de Aurelien.Regat-Barrel
Expert éminent sénior https://www.developpez.com
Le 06/03/2019 à 1:10
Citation Envoyé par stardeath Voir le message
et en parlant de ce cas particulier, puisque c'est une bonne pratique de les mettre, pourquoi finalement ne pas les imposer?
Parce que ça casse la compatibilité avec le code legacy qui en est dépourvu. Les compilos modernes émettent cependant un warning... qui peut librement être converti en erreur... des outils open source peuvent réécrire et migrer automatiquement le code legacy... n'est-ce pas suffisant?

Citation Envoyé par stardeath Voir le message
et, perso, si on doit en mettre qu'un, j'aurais été le premier content à écrire "override void toto()".
pour que cette syntaxe fonctionne, il faut que override soit un nouveau mot clé réservé et non plus un mot clé contextuel, ce qui a pour conséquences de briser la compatibilité: la moindre ligne de code avec une variable ou une fonction nommée "override" ne compilera plus. A titre d'exemple, chez Google c'est plus de 250M de LOC qu'il faut migrer à chaque nouvelle norme...

Citation Envoyé par stardeath Voir le message
on va encore dire que je m'énerve, mais en quoi c'est du troll?, c'est fou quand même une fois de plus cette propension à dénigrer les propos auquel vous n'adhérez pas, de plus, on est pas sur d'autre langage, on est sur le c++. donc si vous ne voulez pas argumenter ou autre, abstenez vous, vous verrez c'est encore plus facile que d'essayer de tourner en dérision des propos ...
et même, donc on met un truc bien pour faire passer la pilule du truc moins bien? c'est quoi cette logique?
ben la logique à questionner c'est d'abord la tienne : c'est toi qui t'acharnes à dénigrer le langage sur la base d’éléments plutôt... subjectifs. J'ai dit que c'est du troll parce qu'on coupe les cheveux en quatre sur un point de détail dans le but de démontrer la faiblesse syntaxique du langage et la stupidité du comité de normalisation, tout en se gardant bien de donner des exemples où la syntaxe C++ est plus simple que dans bien des langages, ni se poser plus humblement la question de pourquoi la comité a pris telle ou telle décision à l'issu de plusieurs années de délibération pour mieux conclure "puisque je n'y vois aucun intérêt, c'est forcément que c'est stupide".

Des critiques sur C++ j'en ai entendu un paquet, mais jamais sur override en fin de prototype. Toi même admet que c'est parce que tu dois parser le langage dans un contexte bien précis que ça te pose problème. Mais sinon, quand on a pris l'habitude de déclarer ses fonction const, ça choque pas plus que ça (et pour les long noms de fonction y'a clang-format qui fait très bien le job).

A savoir beaucoup de pistes ont été étudiées et débattues pour le cas d'override (comme tout le reste d'ailleurs), et la lisibilité du langage est toujours au coeurs des débats. Il suffit de chercher un peu sous Google pour avoir le détail des propositions avec argumentation de leur rejet:
http://www.open-std.org/jtc1/sc22/wg...2005/n1827.htm
http://www.open-std.org/jtc1/sc22/wg...009/n2852.html

Citation Envoyé par stardeath Voir le message
j'écris des outils d'analyses du code c++, je sais pas si vous imaginez le bordel que c'est de gérer le simple cas du virtual/override/final ; le tout avec un bénéfice de la rétrocompatibilité syntaxique, pour moi, nul.
tu ne peux pas t'appuyer sur un front-end éprouvé qui fait déjà tout ça pour toi?
6  0 
Avatar de JolyLoic
Rédacteur/Modérateur https://www.developpez.com
Le 10/03/2019 à 0:03
Je ne suis pas en faveur du mélange de code de plusieurs versions du C++ à grains fins dans le même projet, pour plusieurs raisons :
- Déjà, celle expliquées par Aurélien qui font que ça aurait un mauvais impact sur l'évolution du code
- Ensuite à cause de la difficulté énorme pour un développeur qui devrait à chaque instant maîtriser non pas 1 version de la norme (le sous ensemble commun mis en oeuvre par ses compilateurs actuels), mais plusieurs en même temps
- Finalement, je pense que comme les différences vont bien au délà de la syntaxe, il va y avoir plein de problème aux interfaces... Quelques exemples sans vraiment réfléchir profondément :
- Un fonction C98 prend un argument par valeur. Je l'appelle dans un contexte C++11 avec un temporaire. Ce dernier doit-il être copié (sémentique C++98) ou déplacé (sémentique C++11) ?
- Ai-je le droit de faire dans un code C++11 un memcpy d'un objet défini en C++98 qui n'est pas un POD mais est triviallement copiable ?
- Deux séquences de token identiques sont-elles ODR-equivalent si elles ne sont pas dans la même version de la norme ?
- Est-ce que je peux instantier un template C++98 avec un argument C++17 ? Quelle version de la norme sera utilisée pour interpréter le code résultant de cette instantiation ? Si on dit C++98, il risque d'y avoir plein de truc étranges dans l'argument que le compilateur ne comprendra pas. Si on dit C++17, on risque d'avoir des soucis si le code C++98 n'est plus considéré comme valide justement parce que le but de cette mécanique est de pouvoir ne plus le considérer comme valide...
- Même question en remplaçant "template" par "macro"...
- Et je ne fais probablement qu'effleurer la surface...

Dit autrement, je pense que ça pourrait peut-être marcher au niveau syntaxique et code généré, mais j'ai du mal à voir ce que ça pourrait donner au niveau préprocesseur et surtout sémantique...
6  0 
Avatar de Pyramidev
Expert confirmé https://www.developpez.com
Le 26/02/2019 à 13:59
Enfin les modules !!!
5  0 
Avatar de Aurelien.Regat-Barrel
Expert éminent sénior https://www.developpez.com
Le 27/02/2019 à 1:27
Citation Envoyé par Mingolito Voir le message
l'avenir c'est clairement le langage xxx qui n'a que des avantages
https://blog.daftcode.pl/hype-driven...t-3469fc2e9b22
5  0 
Avatar de jo_link_noir
Membre émérite https://www.developpez.com
Le 27/02/2019 à 1:38
Citation Envoyé par G_EREMY Voir le message
Bah déjà (1) l'héritage multiple, (2) l'héritage par spécialisation, (3) le multi-thread, le multi-processus, et tout ce qui concerne le système.
1) La plupart supportent l'héritage multiple d'interface et l’injection de trait (directement à l'intérieur d'une classe ou de manière externe).
2) Du CRTP ? C'est vrai que de manière générale les autres langages sont plus limitants au niveau du fonctionnement des templates.
3) Ce n'est pas du ressort du C++, mais des bibliothèques. Après, pour les quelques mots clefs comme thread_local, je pense qu'on peut trouver des équivalents.

utiliser correctement les mécanismes du C++ visant à optimiser son programme, et on peut aller encore plus loin si on décide d'être vraiment bas niveau, et donc d'éviter au maximum d'utiliser la librairie STL)
La STL est optimisation/bas niveau n'est pas incompatible. Il y a certaines parties qui peuvent être problématique, mais une bonne partie est censé être performant. Si ce n'est pas le cas, la meilleure chose à faire est de patcher les implémentations pour que tous le monde en profite.

est-ce prévu de pouvoir restreindre les types génériques (comme en Java par exemple) ?
Les concepts devraient permettre cela. Actuellement on peut le faire avec std::enable_if/SFINAE ou des static_assert.

Et est ce que c'est prévu qu'ils règlent le problème où l'on doit inclure le fichier source dans le header quand on fait de la généricité ?
Ce n'est pas possible pour plusieurs raisons:

- Le prototype peut dépendre de l'implémentation, par exemple avec une fonction qui retourne auto.
- Les instances de fonction template n'existe qu'au moment de leur utilisation. Pour les mettre dans un .cpp, il faudrait alors instancier les mêmes fonctions dans le cpp pour ne pas avoir des erreurs de link. On peut utiliser des instanciations explicite et extern(?), mais cela cause d'autre soucis pour une classe: toutes les fonctions doivent compiler, même si elles ne sont jamais utilisées.

Pour la séparation, le plus commun reste de mettre les implémentations dans un .tpl, tcc, .inl, .whatever et de l'inclure en fin du fichier d'en-tête.

C'est le côté moche du C++ je trouve Surtout que du coup on ne peut pas faire du using namespace dans le fichier source auquel cas cela va se répercuter dans les autres fichiers sources.
Il doit bien y avoir moyen de le faire en jouant avec les namespaces

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
namespace malib {
  namespace impl {
    using namespace std;
    namespace v1 {
      // ...
    }
  }
  using namespace impl::v1;
}


Après perso, je préfère écrire le namespace ou mettre un alias dessus.
5  0 
Avatar de Aurelien.Regat-Barrel
Expert éminent sénior https://www.developpez.com
Le 04/03/2019 à 17:20
Citation Envoyé par stardeath Voir le message
qu'est ce qui est passé par la tête du comité pour se dire que par exemple ça : virtual int foo() override
c'est acceptable niveau syntaxe? (et ça c'est encore gentillet comme exemple de stupidité)
cette syntaxe est déconseillé par les guidelines officielles C++ (c'est à dire par le comité):
https://github.com/isocpp/CppCoreGui...md#Rh-override
un outil tel que clang-tidy peut automatiquement détecter et même transformer ce genre de cas.

Après c'est bien de troller sur l'emplacement d'un mot-clé, mais C++ possède aussi ses atouts même au niveau syntaxique (compare comment créer une map de tuples par exemple...). C++ permet de se passer plus facilement des pointeurs que pas mal d'autres langages, dont certains imposent même la virtualité sur chaque méthode... c'est quand même délirant.

Pour ce qui est de la rétrocompatibilité, C++ considère que c'est une feature. Sur de petits projets (de l'ordre de 100.000 lignes) cela peut paraître inutile, mais sur de gros projets (plusieurs missions de LOC) on voit les choses différemment... et des projets de 15 ans d'âge / plusieurs millions de lignes en C++, il y en a... beaucoup. C'est là une différente importante avec beaucoup d'autres langages.
5  0 
Contacter le responsable de la rubrique Accueil

Partenaire : Hébergement Web