Bibliothèque standard du jour de la mort

L'autre jour à Prague, le comité de normalisation C ++ a mené une série d'enquêtes sur la question de la modification de l'ABI, et finalement il a été décidé de ne rien y changer. Il n'y eut pas d'applaudissements dans la salle.
Je pense que nous n'avons pas pleinement réalisé les conséquences que cette décision entraînerait, et je ne pense pas qu'en principe, elle puisse affecter positivement le développement de la langue.



Qu'est-ce que l'ABI?


ABI - un ensemble de conventions qui définissent comment votre programme est représenté sous forme binaire, comment les noms y sont déclarés, le balisage de classe est défini et les conventions d'appel de fonction sont définies. En fait, c'est une sorte de protocole binaire, mais il n'est pas versionné.
Afin de ne pas vous confondre dans la terminologie, regardons des exemples de ce que le changement ABI implique et sa répartition dans le programme:

Vous ne pouvez pas utiliser le symbole exporté dans la nouvelle version de votre bibliothèque compilée si vous avez fait l'une des choses suivantes:

  • Ajout d'un nouveau champ à une classe existante
  • Modification des paramètres de modèle de la classe / fonction, transformation de la fonction de modèle en un non-modèle, ou vice versa, ajout d'un modèle variadic
  • Appliquer le spécificateur en ligne à quelque chose
  • Ajout de paramètres par défaut dans la déclaration de fonction
  • Annonce d'une nouvelle méthode virtuelle

Et bien plus encore, mais les exemples ci-dessus sont les principaux mentionnés par le comité, et ceux-là mêmes, grâce auxquels la plupart des propositions de la norme sont détruites sur place. J'ai omis les options de violation de l'ABI, pendant lesquelles le code source du programme se casse également (par exemple, suppression ou modification de fonctions). Cependant, ce n'est pas toujours vrai. Par exemple, la suppression d'une fonction n'implique pas toujours la rupture du code source. std::stringIl a un opérateur de conversion std::string_view, dont je me débarrasserais volontiers, et bien que le supprimer cassera l'ABI, cela ne conduira pas à des problèmes importants dans le code source.

Pourquoi devrions-nous briser ABI


Tout d'abord, il y a plusieurs changements utiles dans l'implémentation de la bibliothèque standard que vous pouvez implémenter si vous cassez l'ABI actuel:

  • Rendre les conteneurs associatifs (beaucoup) plus rapides
  • Accélérez votre travail std::regex(pour le moment, il est plus rapide d'exécuter PHP et de le rechercher avec une expression régulière que d'utiliser celle standard std::regex)
  • Quelques changements dans std::string, std::vectorainsi que dans la disposition des autres conteneurs
  • Unité de l'interface de classe: pour le moment, certaines de leurs implémentations ne correspondent pas intentionnellement à une seule interface pour des raisons de stabilité ABI

Plus important encore, il y a des changements dans la conception de la bibliothèque qui ne peuvent pas être effectués sans rencontrer le problème de sécurité ABI. Voici une liste incomplète de tout ce qui n'est pas possible actuellement pour la raison mentionnée ci-dessus:

  • std::scoped_lock a été ajouté afin de ne pas casser le changement abi lock_guard
  • int128_t , intmax_t. , , , intmax_t deprecated
  • std::unique_ptr , zero-overhead
  • error_code - , ABI
  • status_code ABI
  • recursive_directory_iterator , ABI
  • <cstring> constexpr ( strlen) , ABI
  • UTF-8 std::regex — ABI
  • l'ajout de la prise en charge reallocet le retour de la taille de la mémoire allouée sont une ventilation ABI pour les allocateurs polymorphes
  • Création de destructeurs virtuels implicites pour les types polymorphes
  • le type de retour y push_backpeut être modifié si l'ABI actuel est cassé
  • En général, avons-nous vraiment besoin de et push_back, et emplace_back?
  • std::shared_ptr provoque également une panne ABI
  • [[no_unique_address]] pourrait être sorti par le compilateur si nous ne nous soucions pas de sauvegarder l'ABI actuel

Et la liste ne s'arrête pas là. Je pense que le WG21 devrait essayer de tenir à jour la liste de ces choses. Mais je prendrai note de tous ceux qui disent «ça va casser l'ABI», étant avec moi dans la même pièce.

Que voulons-nous changer d'autre?


Je ne sais pas. Et je ne sais pas ce que je ne sais pas. Mais si on me demandait de deviner, je dirais ce qui suit:

  • C++23 ABI, - , ABI.
  • , , , , ABI
  • ABI,
  • , ABI
  • Tombstone ABI

ABI


Au cours de la dernière discussion ABI, un certain nombre d'enquêtes ont été menées à Prague, qui, cependant, ne nous disent rien. Selon que vous êtes pessimiste ou optimiste, les résultats actuels peuvent être interprétés différemment par vous.

Faits marquants:

  • WG21 ne veut pas casser ABI en 23
  • WG21 estime nécessaire de casser l'ABI dans les futures versions de C ++ (C ++ 26 ou ultérieur)
  • Le WG21 prendra du temps pour examiner les propositions qui violent l'ABI
  • WG21 ne promet pas une stabilité éternelle
  • Le WG21 considère qu'il est important de maintenir la priorité sur les performances, même au détriment de la stabilité de la langue

Ces déclarations contiennent de nombreux points importants, mais il n'y a pas de consensus. Curieusement, le comité s'est divisé en deux.

Voyance


Dans quelle version de C ++ attendre les changements


L'inconvénient évident de tous ces sondages est que nous n'avons pas décidé quand exactement nous voulons briser l'ABI.

en c ++ 23? Non, certainement pas déjà.

en C ++ 26? Certaines personnes ont l'intention de voter pour, mais une autre partie est susceptible de voter pour C ++ 41 ou pour le moment où ils prendront leur retraite et ils n'ont pas à soutenir leur projet actuel. L'une des questions vient de mentionner C ++ - certains ; très confortablement!

Il n'y a aucune raison de croire que si l'ABI ne peut pas être violé maintenant, il peut l'être plus tard. Les personnes qui ont besoin de stabilité ont plusieurs années de retard sur la norme. Donc, si nous ne le cassons pas maintenant, les gens continueront de compter sur l'ABI jamais promis, peut-être encore dix ou même vingt ans. Le simple fait que nous ayons mené cette enquête a finalement voté pour ne pas violer l'ABI, montre que l'ensemble de l'écosystème devient progressivement caillouteux et stagnant - chaque jour, le problème ne fait qu'empirer et potentiellement plus cher.

Je ne pense pas que quelque chose va changer dans l'enquête menée dans trois ans. C’est comme le réchauffement climatique: tout le monde est d’accord qu’un jour nous devons nous attaquer à ce problème. Et puis interdisons le diesel en 2070?

Tout ce qui n'est pas prévu d'être fait au cours des cinq prochaines années ne se produira probablement jamais.

À propos des offres qui violent ABI


Le WG21 a voté pour consacrer plus de temps aux propositions qui violent l'ABI actuel. Cela signifie plusieurs choses:

  • Nous allons perdre plus de temps dans l'une des salles les plus bruyantes du comité pour discuter de cette question et en laisser moins sur les propositions qui ont plus de chances d'être adoptées, et finalement nous les rejetterons tout de même
  • Nous chercherons des alternatives qui ne cassent pas l'ABI (cela sera discuté ci-dessous)
  • Des modifications partielles de l'ABI peuvent être introduites (voir également ci-dessous)

Les performances sont plus importantes que la stabilité ABI


C'est comme demander si un enfant de cinq ans veut un bonbon. Bien sûr, nous voterons sur l'importance de la performance. Cependant, je crains que certaines personnes continuent de voter contre.

Il me semble que le comité veut en même temps s'asseoir sur deux chaises à la fois. Et c'est impossible:
Bryce Adelstein Lelbach @blebach
- Performance
- Stabilité ABI
- Possibilité de changer quelque chose

Choisissez deux options parmi celles proposées.

la stabilité du langage et ABI, bien sûr, entrent en collision, nous obligeant à poser une question aussi fondamentale - Qu'est-ce que C ++ et quelle est sa bibliothèque standard?

Habituellement, dans ce cas, les termes «performance», « abstraction à coût nul », « ne payez pas pour ce que vous n'utilisez pas » sont mémorisés . Et la stabilité d'ABI se situe à travers tout cela.

Des conséquences d'une portée considérable


image

Je suis profondément convaincu que la décision de ne pas casser l'ABI au cours de la 23e année est la plus grosse erreur que le comité ait jamais commise. Et je sais que certaines personnes croient le contraire. Mais voici ce qui risque de se produire bientôt:

Cauchemar d'apprentissage


Soyons honnêtes. Tous les programmes qui reposent sur ABI sont susceptibles de violer les principes ODR quelque part ou d'utiliser des indicateurs incompatibles, qui, heureusement, fonctionnent toujours.

Les nouveaux programmes doivent être compilés à partir du code source, nous avons besoin d'outils construits sur l'assemblage à partir des sources, et non d'une collection de bibliothèques que nous avons obtenues quelque part et insérées d'une manière ou d'une autre dans le projet.

Oui, la construction à partir des sources est quelque chose qui n'est pas si facile à réaliser. Mais nous devons encourager cette approche du produit, mettre à jour régulièrement les compilateurs afin que les utilisateurs bénéficient des fonctionnalités nouvellement introduites un mois après la sortie, et pas dix ans plus tard. Des solutions appropriées, fiables, évolutives et reproductibles, des bibliothèques open source et un système de dépendance doivent être encouragés.

Refusant de violer ABI, le comité déclare ouvertement qu'il soutiendra des programmes mal écrits tout au long de leur existence. Même si vous ne liez pas aux bibliothèques obtenues via apt-install (qui sont en fait destinées au système), il y aura d'autres personnes, car le comité leur a donné leur bénédiction.

C'est un énorme pas en arrière. Comment pouvons-nous enseigner aux autres de bonnes pratiques linguistiques si nous ne sommes pas incités à le faire?

Perte d'intérêt pour la bibliothèque standard


La perte estimée des performances de la bibliothèque due à notre réticence à violer ABI est estimée à 5-10%. Ce nombre ne fera qu'augmenter avec le temps. Regardons des exemples:

  • Si vous êtes une grande entreprise, vous pouvez vous acheter un nouveau centre de données ou payer une équipe de programmeurs qui prendraient en charge leur propre bibliothèque
  • , 5% ,
  • , 5-10% , VR-
  • , —

Je pense qu'ici, bon gré mal gré, la question se pose entre: «Je devrais certainement utiliser C ++ et sa bibliothèque standard!» et "Peut-être que je ne devrais pas utiliser la bibliothèque standard? Ou peut-être que je ne devrais pas utiliser C ++ en principe? Peut-être que .NET, julia ou Rust seraient une meilleure solution? " Bien sûr, de nombreux facteurs influencent la réponse, mais nous voyons ce qui se passe récemment.

De nombreux développeurs de jeux sont extrêmement sceptiques quant à la bibliothèque standard. Ils préfèrent développer leur propre alternative, comme EASTL , plutôt que de profiter de STL. Facebook a de la folie , Google a du rappel et ainsi de suite.

C'est comme une boule de neige. Si les gens n'utilisent pas la bibliothèque standard, ils n'ont aucun intérêt à l'améliorer. La performance est le facteur clé qui maintient la bibliothèque à flot. Sans garantie de performance, beaucoup moins d'efforts seront consacrés à son développement.
>> Jonathan Müller @foonathan
Quel est l'intérêt d'utiliser des conteneurs de la bibliothèque standard s'ils n'offrent pas de meilleures performances?

Titus Winters @TitusWinters
Peut-être parce qu'ils sont communs et facilement accessibles? (ces deux faits ne signifient pas la même chose).
Voter pour préserver ABI revient à dire que la bibliothèque standard devrait s'efforcer d'être McDonald's - elle est également partout, elle est stable et résout techniquement les tâches.

Comment un comité peut-il considérer les propositions de rupture d'un ABI?


Plusieurs options sont proposées pour soulager la douleur causée par l'incapacité d'accepter les offres si elles violent l'ABI:

Ajout de nouveaux noms


image

C'est la première et évidente solution. Si nous ne pouvons pas changer std::unordered_map, pouvons-nous simplement ajouter std::fast_map? Il y a plusieurs raisons pour lesquelles c'est mauvais. L'ajout de types à la bibliothèque standard coûte cher, à la fois en termes de coûts de support et en termes d'éducation. Après l'introduction de la nouvelle classe, des milliers d'articles apparaîtront inévitablement, expliquant quel conteneur doit être utilisé. Par exemple, dois-je utiliser std::scoped_lockou std::lock_guard? Je n'ai aucune idée! J'ai besoin de google à chaque fois. Il y a aussi le problème que les bons noms finissent tôt ou tard. Nous obtenons également une surcharge lors de l'exécution du programme, car tous les conteneurs doivent être constamment convertis les uns aux autres, il devient difficile de contrôler un grand nombre de surcharges de conversion dans la classe, etc.

C'est ironique, mais les personnes qui soutiennent la solution ci-dessus peuvent également affirmer que C ++ est un langage trop complexe. L'ajout de doublons à la bibliothèque ne facilitera certainement pas la tâche.

Mais nous pourrions accepter cette offre comme standard!


Certains développeurs de bibliothèques affirment que leurs offres ont été rejetées en raison d'une violation d'ABI, bien qu'elles n'aient en fait rien violé, ou qu'elles pourraient être modifiées afin de contourner l'échec d'ABI.

En tant que personne cynique, c'est un peu difficile pour moi de croire. Le fait est qu'avant il n'y avait pas de telles propositions, et les scénarios dans lesquels elles peuvent être appliquées sont très limités. ABI Review Group (ARG) pourrait vous aider dans cette affaire, mais ils recommanderont probablement un autre nom pour la classe / fonction.

Violation partielle d'Abi


L'idée principale n'est pas de casser l'intégralité de l'ABI, mais de le changer uniquement pour une classe ou une fonction spécifique. Le problème avec cette approche est qu'au lieu d'une erreur au stade de la liaison, nous verrons le problème déjà lors du lancement du programme, et il sera désagréable de nous surprendre. Le comité avait déjà essayé cette approche en C ++ 11 lorsqu'il a modifié le balisage std::string. Rien de bon n'en est sorti. Tout était si mauvais que ce fait est toujours utilisé comme argument en faveur du maintien de l'ABI actuel.

Un autre niveau d'indexation


La solution à certains des problèmes avec ABI serait la possibilité d'accéder aux données de la classe via un pointeur, puis le balisage de la classe ne serait que ce pointeur. L'idée est très proche de l'idiome PIMPL , qui est activement utilisé dans Qt en raison de son ABI. Oui, cela résoudrait le problème avec les membres de la classe, mais que faire des méthodes virtuelles?

Considérant le problème d'un point de vue plus critique, nous parlons d'ajouter un niveau d'indirection supplémentaire (index de pointeur) et une allocation supplémentaire de mémoire dans le tas pour tout ce qui est inclus dans le cadre d'ABI. En STL, en fait, tout est enfermé dans ce cadre car il s'agit d'une collection de classes généralisées.

En conséquence, le prix de cette approche sera énorme.

Pour résoudre ce problème, la norme contient déjà plusieurs propositions. Certains d'entre eux veulent faire de PIMPL l'une des fonctionnalités du langage, vous pouvez donc choisir entre stabilité ABI et hautes performances.

Ironiquement, cependant, mais pour transformer les types de bibliothèques en types PIPML, nous devons ... casser l'ABI.

Réassemblez tout le code tous les trois ans


Juste mes pensées à voix haute.

Toutes les offres actuelles de la norme doivent être détruites


Paradoxalement, le C ++ n'a jamais été aussi vivant qu'aujourd'hui. À Prague, 250 personnes ont travaillé sur beaucoup de choses pour lui, notamment:

  • Numérique
  • Algèbre linéaire
  • l'audio
  • Unicode
  • E / S asynchrones
  • Graphiques 2D et 3D
  • De nombreuses autres fonctionnalités

Toutes ces propositions sont unies par un fait commun - elles sont beaucoup plus facultatives par rapport à ce que nous avons actuellement dans la norme. Les gens essaient simplement de standardiser les choses de leur domaine de recherche et de travail, ou de ce qui évolue et change constamment.
En particulier, les algorithmes Unicode sont extrêmement instables et changent rapidement au fil du temps.

Et puis, une horreur telle que le réseautage se profile à l'horizon . Il est très, très irresponsable d'essayer de standardiser tout ce qui pourrait entraîner des problèmes de sécurité, et en même temps de ne pas pouvoir le changer plus tard (rappelez-vous d'ABI).

Puisque C ++ a décidé de le rendre stable, toutes ces suggestions doivent être détruites et brûlées. Je ne voudrais pas être détruit, mais cela doit être fait.

Mais ils ne le feront toujours pas.

Dans le meilleur des cas, nous ne commettrons pas d'erreurs et ne normaliserons pas l'état actuel des choses dans l'une des nouvelles versions de C ++, puis nous laisserons tout se décomposer lentement, car il ne sera pas possible de le réparer (dans le cas de Networking TS, nous semblons ne pouvoir rien changer du tout, donc nous devrons standardiser ce qui existait il y a dix ans, alors bien sûr la bibliothèque peut encore être considérablement améliorée, mais laissons cette histoire pour une autre fois).

Mais bien sûr, nous ferons beaucoup, beaucoup d’erreurs.

>> Ólafur Waage @olafurw
( , )

, !

. , ( : , , )?

Hyrum Wright @hyrumwright
, , . — , .

Certaines erreurs sont commises intentionnellement, car ce sont des compromis, tandis que d'autres passent inaperçues pendant de nombreuses années.

Le temps passe, mais la bibliothèque standard reste immobile. Les compromis précédemment effectués commencent progressivement à nous déranger et deviennent plus tard de véritables «goulots d'étranglement» dans le code existant.

Certaines choses sont vraiment impossibles à changer, car elles sont intégrées dans l'API. Nous avons tous une idée de la difficulté de changer une API existante. Mais une partie du code peut toujours être corrigée et améliorée si nous pouvions casser l'ABI.

Le C ++ sera toujours à flot au cours des 40 prochaines années. Si nous ne pouvons pas réaliser le besoin de le changer de manière imprévisible à tout moment, alors le seul bon choix sera de ne pas jouer à ce jeu en principe.

Tout le monde sait qu'un conteneur associatif standard est pertinent pour une utilisation depuis moins de dix ans. Mais pourquoi pensons-nous alors que les propositions plus importantes de la norme seront plus efficaces?

Votre offre au standard sera détruite, la mienne sera détruite de la même manière.

Un comité peut-il en principe casser un ABI?


Beaucoup sont sûrs que le comité ne peut pas, en principe, prendre une telle décision, car alors les développeurs de bibliothèque l'ignoreront simplement. Tout cela ressemble douloureusement à la lutte à bras, dans laquelle le comité a décidé de ne pas jouer.

Mais le fait est que les développeurs de tout produit ont leurs propres utilisateurs. Les utilisateurs sont ceux qui doivent avant tout comprendre les compromis qui leur sont imposés.

Beaucoup de gens comptent sur ABI par accident, sans faire de choix éclairé. Beaucoup de gens comptent également sur la stabilité, car, bien sûr, tout le monde veut y compter. Mais comme toute autre chose, la stabilité a un prix, et maintenant tout l'écosystème C ++ en paie.

All Articles