{"id":32466,"date":"2019-10-31T21:47:13","date_gmt":"2019-10-31T18:47:13","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17\/"},"modified":"2019-10-31T21:47:13","modified_gmt":"2019-10-31T18:47:13","slug":"kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17","title":{"rendered":"Comment nous avons traduit 10 millions de lignes de code C++ vers la norme C++14 (puis vers C++17)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Il y a quelque temps (\u00e0 l'automne 2016), lors du d\u00e9veloppement d'une nouvelle version de la plateforme technologique 1C:Entreprise, la question de la prise en charge de la nouvelle norme s'est pos\u00e9e au sein de l'\u00e9quipe de d\u00e9veloppement. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B14\">C++14<\/a><\/noindex> dans notre code. La transition vers la nouvelle norme, comme nous le pensions, nous permettrait d'\u00e9crire de nombreuses choses de mani\u00e8re plus \u00e9l\u00e9gante, simple et fiable, facilitant la maintenance et le support du code. Et dans cette traduction, il n'y a apparemment rien d'extraordinaire, si ce n'est l'ampleur de la base de code et les caract\u00e9ristiques sp\u00e9cifiques de notre code.<\/p>\n<p>Pour ceux qui ne le savent pas, 1C:Entreprise est un environnement de d\u00e9veloppement rapide d'applications m\u00e9tiers multiplateformes et un runtime pour leur ex\u00e9cution sur diff\u00e9rents syst\u00e8mes d'exploitation et SGBD. En gros, le produit comprend :<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000885.htm\">Un cluster de serveurs d'applications<\/a><\/noindex>, fonctionnant sous Windows et Linux<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000124.htm\">Client<\/a><\/noindex>, interagissant avec le serveur via http(s) ou via son propre protocole binaire, fonctionnant sous Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/315414\/\">Un client web<\/a><\/noindex>, fonctionnant dans les navigateurs Chrome, Internet Explorer, Microsoft Edge, Firefox, Safari (\u00e9crit en JavaScript)<\/li>\n<li>Un environnement de d\u00e9veloppement (<noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000008.htm\">Configurateur<\/a><\/noindex>), fonctionnant sous Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000813.htm\">Outils d'administration<\/a><\/noindex> des serveurs d'applications, fonctionnent sous Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/wonderland.v8.1c.ru\/blog\/mobilnyy-klient\/\">Un client mobile<\/a><\/noindex>, se connectant au serveur via http(s), fonctionnant sur des appareils mobiles sous Android, iOS, Windows<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/283198\/\">Une plateforme mobile<\/a><\/noindex> \u2014 un framework pour la cr\u00e9ation d'applications mobiles hors ligne avec possibilit\u00e9 de synchronisation, fonctionnant sous Android, iOS, Windows<\/li>\n<li>Environnement de d\u00e9veloppement <noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/IDE\/\">Outils de d\u00e9veloppement 1C:Entreprise<\/a><\/noindex>, \u00e9crit en Java<\/li>\n<li>Serveur <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/422903\/\">Syst\u00e8mes d'Interaction<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nNous essayons au maximum d'\u00e9crire un seul code pour diff\u00e9rents syst\u00e8mes d'exploitation \u2014 la base de code du serveur est commune \u00e0 99%, celle du client \u2014 environ 95%. La plateforme technologique 1C:Entreprise est principalement \u00e9crite en C++ et voici les caract\u00e9ristiques approximatives du code :<\/p>\n<ul>\n<li>10 millions de lignes de code C++<\/li>\n<li>14 000 fichiers,<\/li>\n<li>60 000 classes,<\/li>\n<li>500 000 m\u00e9thodes.<\/li>\n<\/ul>\n<p>\nEt tout cela devait \u00eatre traduit vers C++14. Nous allons aujourd'hui vous raconter comment nous avons fait cela et les d\u00e9fis que nous avons rencontr\u00e9s en cours de route.<\/p>\n<p><img decoding=\"async\" alt=\"Comment nous avons traduit 10 millions de lignes de code C++ vers la norme C++14 (puis vers C++17)\" src=\"\/wp-content\/uploads\/2019\/04\/7f9270bc37fa9fd462ac9efbb12f0764.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Avertissement<\/h3>\n<p>\nTout ce qui est \u00e9crit ci-dessous concernant le fonctionnement lent\/rapide et la consommation (non) significative de m\u00e9moire des r\u00e9alisations des classes standard dans diverses biblioth\u00e8ques signifie une chose : c'est valable POUR NOUS. Il est tout \u00e0 fait possible que pour vos t\u00e2ches, les r\u00e9alisations standard conviennent le mieux. Nous, en revanche, nous appuyons sur nos propres t\u00e2ches : nous prenons des donn\u00e9es typiques pour nos clients, nous les testons avec des sc\u00e9narios typiques, nous examinons les performances, le volume de m\u00e9moire consomm\u00e9e, etc., et nous analysons si ces r\u00e9sultats nous conviennent \u00e0 nous et \u00e0 nos clients ou non. Et nous agissons en cons\u00e9quence.<\/p>\n<h3>Ce que nous avions<\/h3>\n<p>\nAu d\u00e9part, nous avons \u00e9crit le code de la plateforme 1C:Enterprise 8 sur Microsoft Visual Studio. Le projet a commenc\u00e9 au d\u00e9but des ann\u00e9es 2000 et nous n'avions qu'une version pour Windows. Naturellement, depuis lors, le code a \u00e9volu\u00e9 activement, de nombreux m\u00e9canismes ont \u00e9t\u00e9 compl\u00e8tement r\u00e9\u00e9crits. Mais le code \u00e9tait \u00e9crit selon la norme de 1998, et par exemple, nos crochets droits \u00e9taient s\u00e9par\u00e9s par des espaces pour permettre une compilation r\u00e9ussie, comme ceci :<\/p>\n<pre><code class=\"cpp\">vector&lt;vector&gt; IntV;<\/code><\/pre>\n<p>\nEn 2006, avec la sortie de la version 8.1 de la plateforme, nous avons commenc\u00e9 \u00e0 prendre en charge Linux et avons migr\u00e9 vers une biblioth\u00e8que standard tierce <noindex><a rel=\"nofollow\" href=\"http:\/\/www.stlport.org\/\">STLPort<\/a><\/noindex>. L'une des raisons de cette migration \u00e9tait la gestion des cha\u00eenes larges. Dans notre code, nous utilisons massivement std::wstring, bas\u00e9 sur le type wchar_t. Sa taille sous Windows est de 2 octets, tandis qu'elle est par d\u00e9faut de 4 octets sous Linux. Cela entra\u00eenait une incompatibilit\u00e9 de nos protocoles binaires entre le client et le serveur, ainsi que divers types de donn\u00e9es persistantes. Avec les options de gcc, il est possible d'indiquer que la taille de wchar_t lors de la compilation doit \u00e9galement \u00eatre de 2 octets, mais alors, on peut oublier l'utilisation de la biblioth\u00e8que standard du compilateur, car elle utilise glibc, qui \u00e0 son tour est compil\u00e9e pour un wchar_t de 4 octets. D'autres raisons incluaient une impl\u00e9mentation de meilleure qualit\u00e9 des classes standard, le support des tables de hachage et m\u00eame l'\u00e9mulation de la s\u00e9mantique de d\u00e9placement \u00e0 l'int\u00e9rieur des conteneurs, que nous utilisions activement. Une autre raison, comme on dit, last but not least, \u00e9tait la performance des cha\u00eenes. Nous avions notre propre classe pour les cha\u00eenes, car en raison de la sp\u00e9cificit\u00e9 de notre logiciel, les op\u00e9rations sur les cha\u00eenes sont utilis\u00e9es de mani\u00e8re tr\u00e8s intensive et sont critiques pour nous. <\/p>\n<p>Notre cha\u00eene est fond\u00e9e sur des id\u00e9es d'optimisation des cha\u00eenes qui ont \u00e9t\u00e9 exprim\u00e9es d\u00e8s le d\u00e9but des ann\u00e9es 2000 <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B5%D1%81%D0%BA%D1%83,_%D0%90%D0%BD%D0%B4%D1%80%D0%B5%D0%B9\">par Andrei Alexandrescu<\/a><\/noindex>. Plus tard, lorsque Alexandrescu a travaill\u00e9 chez Facebook, \u00e0 sa demande, une ligne fonctionnant sur des principes similaires a \u00e9t\u00e9 utilis\u00e9e dans le moteur de Facebook (voir la biblioth\u00e8que <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/folly\">folly<\/a><\/noindex>).<\/p>\n<p>. Dans notre ligne, nous avons utilis\u00e9 deux technologies principales d'optimisation :<\/p>\n<ol>\n<li>Pour les valeurs courtes, un tampon interne au sein m\u00eame de l'objet string est utilis\u00e9 (ne n\u00e9cessitant pas d'allocation m\u00e9moire suppl\u00e9mentaire).<\/li>\n<li>Pour toutes les autres, un m\u00e9canisme est utilis\u00e9 : <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9A%D0%BE%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%B8_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D0%B8\">Copy On Write<\/a><\/noindex>. La valeur de la cha\u00eene est stock\u00e9e \u00e0 un seul endroit, lors de l'affectation\/modification, un compteur de r\u00e9f\u00e9rences est utilis\u00e9.<\/li>\n<\/ol>\n<p>\nPour acc\u00e9l\u00e9rer la compilation de la plateforme, nous avons exclu de notre version de STLPort l'impl\u00e9mentation de stream (que nous n'utilisions pas), ce qui nous a donn\u00e9 un gain de compilation d'environ 20 %. Par la suite, nous avons d\u00fb utiliser de mani\u00e8re limit\u00e9e <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Boost\">Boost<\/a><\/noindex>. Boost utilise activement le stream, notamment dans ses API de service (par exemple, pour la journalisation), ce qui nous a oblig\u00e9s \u00e0 le modifier en excluant l'utilisation de stream. Cela, \u00e0 son tour, compliquait notre transition vers de nouvelles versions de Boost. <\/p>\n<h3>La troisi\u00e8me voie<\/h3>\n<p>\nLors de la transition vers la norme C++14, nous avons envisag\u00e9 les options suivantes :<\/p>\n<ol>\n<li>Faire fonctionner notre STLPort modifi\u00e9 sur la norme C++14. L'option est tr\u00e8s compliqu\u00e9e, car le support de STLPort a \u00e9t\u00e9 interrompu en 2010, et nous aurions d\u00fb porter tout son code nous-m\u00eames.<\/li>\n<li>Passer \u00e0 une autre impl\u00e9mentation de STL, compatible avec C++14. Il est extr\u00eamement souhaitable que cette impl\u00e9mentation soit compatible avec Windows et Linux.<\/li>\n<li>Utiliser la biblioth\u00e8que int\u00e9gr\u00e9e au compilateur appropri\u00e9 lors de la compilation pour chaque OS.<\/li>\n<\/ol>\n<p>\nLa premi\u00e8re option a \u00e9t\u00e9 imm\u00e9diatement rejet\u00e9e en raison de l'ampleur des travaux.<\/p>\n<p>Nous avons r\u00e9fl\u00e9chi pendant un certain temps \u00e0 la deuxi\u00e8me option ; comme candidat, nous avons envisag\u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/libcxx.llvm.org\/\">libc++<\/a><\/noindex>, mais \u00e0 l'\u00e9poque, il ne fonctionnait pas sous Windows. Pour porter libc++ sur Windows, il aurait fallu effectuer beaucoup de travail \u2014 par exemple, \u00e9crire nous-m\u00eames tout ce qui concerne les flux, la synchronisation des threads et l'at\u00f4misme, car dans libc++, ces domaines utilisaient <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/POSIX\">POSIX API<\/a><\/noindex>.<\/p>\n<p>Et nous avons choisi la troisi\u00e8me voie.<\/p>\n<h3>Transition<\/h3>\n<p>\nAinsi, nous devions remplacer l'utilisation de STLPort par les biblioth\u00e8ques des compilateurs correspondants (Visual Studio 2015 pour Windows, gcc 7 pour Linux, clang 8 pour macOS). <\/p>\n<p>Heureusement, notre code a \u00e9t\u00e9 principalement \u00e9crit selon les directives et n'utilisait pas de trucs astucieux, donc la migration vers les nouvelles biblioth\u00e8ques s'est d\u00e9roul\u00e9e de mani\u00e8re relativement fluide, gr\u00e2ce \u00e0 des scripts rempla\u00e7ant dans les fichiers sources les noms de types, de classes, d'espaces de noms et d'inclusions. La migration a concern\u00e9 10 000 fichiers sources (sur 14 000). wchar_t a \u00e9t\u00e9 remplac\u00e9 par char16_t ; nous avons d\u00e9cid\u00e9 d'abandonner l'utilisation de wchar_t car char16_t occupe 2 octets sur tous les syst\u00e8mes d'exploitation et ne compromet pas la compatibilit\u00e9 du code entre Windows et Linux.<\/p>\n<p>Il n'a pas manqu\u00e9 de petites aventures. Par exemple, dans STLPort, un it\u00e9rateur pouvait \u00eatre implicitement transform\u00e9 en pointeur sur un \u00e9l\u00e9ment, et \u00e0 certains endroits de notre code, cela \u00e9tait utilis\u00e9. Dans les nouvelles biblioth\u00e8ques, cela n'\u00e9tait plus possible, et ces endroits devaient \u00eatre analys\u00e9s et r\u00e9\u00e9crits manuellement. <\/p>\n<p>Ainsi, la migration du code est termin\u00e9e, le code se compile pour tous les syst\u00e8mes d'exploitation. Il est temps de tester. <\/p>\n<p>Les tests apr\u00e8s la transition ont montr\u00e9 une baisse de performance (jusqu'\u00e0 20-30% \u00e0 certains endroits) et une augmentation de la consommation de m\u00e9moire (jusqu'\u00e0 10-15%) par rapport \u00e0 l'ancienne version du code. Cela \u00e9tait, en particulier, li\u00e9 \u00e0 un fonctionnement sous-optimal des cha\u00eenes de caract\u00e8res standard. Nous avons donc d\u00fb r\u00e9utiliser notre propre cha\u00eene, l\u00e9g\u00e8rement am\u00e9lior\u00e9e. <\/p>\n<p>Une caract\u00e9ristique int\u00e9ressante de l'impl\u00e9mentation des conteneurs dans les biblioth\u00e8ques int\u00e9gr\u00e9es a \u00e9galement \u00e9t\u00e9 mise au jour : les std::map et std::set vides (sans \u00e9l\u00e9ments) des biblioth\u00e8ques int\u00e9gr\u00e9es allouent de la m\u00e9moire. Dans notre cas, en raison des particularit\u00e9s de l'impl\u00e9mentation, un grand nombre de conteneurs vides de ce type sont cr\u00e9\u00e9s \u00e0 certains endroits du code. Les conteneurs standards allouent un peu de m\u00e9moire, pour un \u00e9l\u00e9ment racine, mais cela s'est av\u00e9r\u00e9 critique pour nous - dans plusieurs sc\u00e9narios, nous avons constat\u00e9 une perte significative de performance et une augmentation de la consommation de m\u00e9moire (par rapport \u00e0 STLPort). Nous avons donc remplac\u00e9 dans notre code ces deux types de conteneurs des biblioth\u00e8ques int\u00e9gr\u00e9es par leur impl\u00e9mentation de Boost, o\u00f9 ces conteneurs n'avaient pas cette particularit\u00e9, et cela a r\u00e9solu le probl\u00e8me de ralentissement et d'augmentation de la consommation de m\u00e9moire.<\/p>\n<p>Comme cela arrive souvent apr\u00e8s des changements \u00e0 grande \u00e9chelle dans de grands projets, la premi\u00e8re it\u00e9ration des sources a rencontr\u00e9 quelques probl\u00e8mes, et ici le support des it\u00e9rateurs de d\u00e9bogage dans l'impl\u00e9mentation Windows s'est r\u00e9v\u00e9l\u00e9 tr\u00e8s utile. Pas \u00e0 pas, nous avons avanc\u00e9, et au printemps 2017 (version 8.3.11 1C:Enterprise), la migration a \u00e9t\u00e9 achev\u00e9e. <\/p>\n<h3>R\u00e9sultats<\/h3>\n<p>\nLe passage \u00e0 la norme C++14 a pris environ 6 mois. La majeure partie du temps, un seul d\u00e9veloppeur (tr\u00e8s qualifi\u00e9) a travaill\u00e9 sur le projet, et \u00e0 la phase finale, des membres des \u00e9quipes responsables de domaines sp\u00e9cifiques se sont joints \u2014 UI, serveur de cluster, outils de d\u00e9veloppement et d'administration, etc.<\/p>\n<p>Cette transition a consid\u00e9rablement simplifi\u00e9 notre travail de migration vers les derni\u00e8res versions de la norme. Ainsi, la version 1C:Entreprise 8.3.14 (en cours de d\u00e9veloppement, la sortie est pr\u00e9vue pour le d\u00e9but de l'ann\u00e9e prochaine) est d\u00e9j\u00e0 traduite dans cette norme. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B17\">C++17<\/a><\/noindex>. <\/p>\n<p>Apr\u00e8s la migration, les d\u00e9veloppeurs ont eu plus de possibilit\u00e9s. Autrefois, nous avions notre propre version modifi\u00e9e de la STL et un seul espace de noms std, maintenant notre espace de noms std contient les classes standards des biblioth\u00e8ques int\u00e9gr\u00e9es du compilateur, dans l'espace de noms stdx \u2013 nos cha\u00eenes et conteneurs optimis\u00e9s pour nos t\u00e2ches, et dans boost \u2013 la derni\u00e8re version de boost. Et le d\u00e9veloppeur utilise les classes qui conviennent le mieux \u00e0 ses besoins. <\/p>\n<p>L'impl\u00e9mentation \u00ab native \u00bb des constructeurs de d\u00e9placement (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/move_constructor\">move constructors<\/a><\/noindex>) pour plusieurs classes aide \u00e9galement au d\u00e9veloppement. Si une classe a un constructeur de d\u00e9placement et que cette classe est plac\u00e9e dans un conteneur, la STL optimise la copie des \u00e9l\u00e9ments \u00e0 l'int\u00e9rieur du conteneur (par exemple, lorsque le conteneur est agrandi et qu'il faut modifier la capacit\u00e9 et r\u00e9allouer la m\u00e9moire). <\/p>\n<h3>Une cuill\u00e8re de cendre<\/h3>\n<p>\nLe r\u00e9sultat peut-\u00eatre le plus d\u00e9sagr\u00e9able (mais non critique) de la migration \u2014 nous avons constat\u00e9 une augmentation du volume <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D1%8B%D0%B9_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8C\">des fichiers obj<\/a><\/noindex>, et le r\u00e9sultat complet de la construction avec tous les fichiers interm\u00e9diaires prend d\u00e9sormais entre 60 et 70 Go. Ce comportement est li\u00e9 aux caract\u00e9ristiques des biblioth\u00e8ques standard modernes, qui sont devenues moins critiques quant au volume des fichiers de service g\u00e9n\u00e9r\u00e9s. Cela n'affecte pas le fonctionnement de l'application compil\u00e9e, mais entra\u00eene certains d\u00e9sagr\u00e9ments dans le d\u00e9veloppement, notamment une augmentation du temps de compilation. Les exigences en mati\u00e8re d'espace disque libre sur les serveurs de build et sur les machines des d\u00e9veloppeurs augmentent \u00e9galement. Nos d\u00e9veloppeurs travaillent parall\u00e8lement sur plusieurs versions de la plateforme, et des centaines de gigaoctets de fichiers interm\u00e9diaires cr\u00e9ent parfois des difficult\u00e9s au travail. Ce probl\u00e8me est d\u00e9sagr\u00e9able, mais non critique, et nous avons jusqu'\u00e0 pr\u00e9sent report\u00e9 sa solution. L'une des options envisag\u00e9es pour sa r\u00e9solution est la technique <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Single_Compilation_Unit\">unity build<\/a><\/noindex> (elle est notamment utilis\u00e9e par Google dans le d\u00e9veloppement du navigateur Chrome).<br \/>\n<br \/>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/1c\/blog\/429678\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 (\u043e\u0441\u0435\u043d\u044c\u044e 2016), \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b 1\u0421:\u041f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0442\u0430\u043b \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 C++14 \u0432 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435. \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442, \u043a\u0430\u043a \u043c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0431\u044b \u043d\u0430\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u0438\u0435 \u0432\u0435\u0449\u0438 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u0435\u0439, \u043f\u0440\u043e\u0449\u0435 \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u0435\u0439, \u0443\u043f\u0440\u043e\u0449\u0430\u043b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0438 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430. \u0418 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u043d\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u044d\u043a\u0441\u0442\u0440\u0430\u043e\u0440\u0434\u0438\u043d\u0430\u0440\u043d\u043e\u0433\u043e, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24270,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32466","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 (\u043e\u0441\u0435\u043d\u044c\u044e 2016), \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b 1\u0421:\u041f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0442\u0430\u043b \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u043c\u044b \u043f\u0435\u0440\u0435\u0432\u0435\u043b\u0438 10 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430 C++ \u043d\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 C++14 (\u0430 \u043f\u043e\u0442\u043e\u043c \u0438 \u043d\u0430 C++17) | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 (\u043e\u0441\u0435\u043d\u044c\u044e 2016), \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b 1\u0421:\u041f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0442\u0430\u043b \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:47:13+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:47:13+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Comment nous avons traduit 10 millions de lignes de code C++ en C++14 standard (et ensuite en C++17) | ProHoster","description":"Il y a quelque temps (\u00e0 l'automne 2016), lors du d\u00e9veloppement d'une nouvelle version de la plateforme technologique 1C:Entreprise, la question de la prise en charge de la nouvelle norme s'est pos\u00e9e au sein de l'\u00e9quipe de d\u00e9veloppement.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u043c\u044b \u043f\u0435\u0440\u0435\u0432\u0435\u043b\u0438 10 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430 C++ \u043d\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 C++14 (\u0430 \u043f\u043e\u0442\u043e\u043c \u0438 \u043d\u0430 C++17) | ProHoster","og:description":"\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 (\u043e\u0441\u0435\u043d\u044c\u044e 2016), \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b 1\u0421:\u041f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0442\u0430\u043b \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:47:13+00:00","article:modified_time":"2019-10-31T18:47:13+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32466","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 11:00:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:58:23","updated":"2026-01-21 11:00:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/32466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=32466"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/32466\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/24270"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=32466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=32466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=32466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}