{"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\/de\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17","title":{"rendered":"Wie wir 10 Millionen Zeilen C++-Code auf den Standard C++14 (und dann auf C++17) \u00fcbertragen haben","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Vor einiger Zeit (Herbst 2016) stellte sich im Entwicklungsteam bei der Entwicklung einer neuen Version der technologischen Plattform 1C:Unternehmen die Frage nach der Unterst\u00fctzung des neuen Standards <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B14\">C++14<\/a><\/noindex> in unserem Code. Der Umstieg auf den neuen Standard w\u00fcrde, wie wir annahmen, viele Dinge eleganter, einfacher und zuverl\u00e4ssiger machen und die Wartung und Pflege des Codes erleichtern. Und in der \u00dcbersetzung scheint es nichts Au\u00dfergew\u00f6hnliches zu geben, wenn man nicht die Gr\u00f6\u00dfenordnung der Codebasis und die spezifischen Eigenschaften unseres Codes ber\u00fccksichtigt.<\/p>\n<p>F\u00fcr diejenigen, die es nicht wissen: 1C:Unternehmen ist eine Umgebung f\u00fcr die schnelle Entwicklung von plattform\u00fcbergreifenden Gesch\u00e4ftsanwendungen und eine Runtime f\u00fcr deren Ausf\u00fchrung in verschiedenen Betriebssystemen und Datenbankmanagementsystemen. Im Allgemeinen umfasst das Produkt:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000885.htm\">Ein Cluster von Anwendungsservern<\/a><\/noindex>, l\u00e4uft unter Windows und Linux<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000124.htm\">den Kunden zur\u00fcckzuf\u00fchren sind, nicht verf\u00fcgbar ist.<\/a><\/noindex>, der \u00fcber http(s) oder \u00fcber ein eigenes bin\u00e4res Protokoll mit dem Server kommuniziert, l\u00e4uft unter Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/315414\/\">Web-Client<\/a><\/noindex>, l\u00e4uft in den Browsern Chrome, Internet Explorer, Microsoft Edge, Firefox, Safari (geschrieben in JavaScript)<\/li>\n<li>Die Entwicklungsumgebung (<noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000008.htm\">Konfigurator<\/a><\/noindex>), l\u00e4uft unter Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000813.htm\">Verwaltungstools<\/a><\/noindex> f\u00fcr Anwendungsserver, die unter Windows, Linux, macOS laufen<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/wonderland.v8.1c.ru\/blog\/mobilnyy-klient\/\">Der mobile Client<\/a><\/noindex>, der sich \u00fcber http(s) mit dem Server verbindet, l\u00e4uft auf mobilen Ger\u00e4ten mit Android, iOS, Windows<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/283198\/\">Die mobile Plattform<\/a><\/noindex> \u2014 ein Framework zur Erstellung von Offline-Mobilanwendungen mit Synchronisationsm\u00f6glichkeiten, die unter Android, iOS, Windows laufen<\/li>\n<li>Entwicklungsumgebung <noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/IDE\/\">1C:Enterprise Development Tools<\/a><\/noindex>, geschrieben in Java<\/li>\n<li>Server <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/422903\/\">Interaktionssysteme<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nWir versuchen, den gr\u00f6\u00dftm\u00f6glichen Teil des Codes f\u00fcr verschiedene Betriebssysteme zu schreiben \u2014 die Codebasis des Servers betr\u00e4gt 99%, die des Clients etwa 95%. Die technologische Plattform 1C:Unternehmen ist \u00fcberwiegend in C++ geschrieben, und hier sind die ungef\u00e4hren Merkmale des Codes:<\/p>\n<ul>\n<li>10 Millionen Zeilen C++-Code,<\/li>\n<li>14.000 Dateien,<\/li>\n<li>60.000 Klassen,<\/li>\n<li>eine halbe Million Methoden.<\/li>\n<\/ul>\n<p>\nUnd all das musste auf C++14 umgestellt werden. Heute werden wir dar\u00fcber berichten, wie wir das gemacht haben und mit welchen Herausforderungen wir dabei konfrontiert wurden.<\/p>\n<p><img decoding=\"async\" alt=\"Wie wir 10 Millionen Zeilen C++-Code auf den Standard C++14 (und dann auf C++17) \u00fcbertragen haben\" 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>Haftungsausschluss<\/h3>\n<p>\nAlles, was unten \u00fcber die langsame\/schnelle Leistung, den (nicht) geringen Speicherverbrauch von Implementierungen der Standardklassen in verschiedenen Bibliotheken geschrieben ist, bedeutet eines: Es gilt F\u00dcR UNS. Es ist durchaus m\u00f6glich, dass die Standardimplementierungen f\u00fcr Ihre Aufgaben am besten geeignet sind. Wir haben uns jedoch an unseren Aufgaben orientiert: Wir haben typische Daten unserer Kunden genommen, typische Szenarien damit durchlaufen, die Leistung, den Speicherverbrauch usw. betrachtet und analysiert, ob uns und unseren Kunden solche Ergebnisse akzeptabel sind oder nicht. Und wir haben entsprechend gehandelt.<\/p>\n<h3>Was wir hatten<\/h3>\n<p>\nUrspr\u00fcnglich schrieben wir den Code der Plattform 1C:Enterprise 8 in Microsoft Visual Studio. Das Projekt begann Anfang der 2000er Jahre und wir hatten eine Version nur f\u00fcr Windows. Nat\u00fcrlich hat sich der Code seitdem aktiv entwickelt, viele Mechanismen wurden vollst\u00e4ndig \u00fcberarbeitet. Aber der Code wurde nach dem Standard von 1998 geschrieben, und beispielsweise waren die rechten spitzen Klammern bei uns durch Leerzeichen getrennt, damit die Kompilierung erfolgreich verlief, so:<\/p>\n<pre><code class=\"cpp\">vector&lt;vector &gt; IntV;<\/code><\/pre>\n<p>\nIm Jahr 2006, mit der Ver\u00f6ffentlichung der Version 8.1 der Plattform, begannen wir, Linux zu unterst\u00fctzen und wechselten zu einer externen Standardbibliothek <noindex><a rel=\"nofollow\" href=\"http:\/\/www.stlport.org\/\">STLPort<\/a><\/noindex>. Einer der Gr\u00fcnde f\u00fcr den Wechsel war die Arbeit mit breiten Zeichenfolgen. In unserem Code verwenden wir \u00fcberall std::wstring, basierend auf dem Typ wchar_t. Seine Gr\u00f6\u00dfe betr\u00e4gt in Windows 2 Bytes, in Linux standardm\u00e4\u00dfig 4 Bytes. Dies f\u00fchrte zu Inkompatibilit\u00e4t unserer bin\u00e4ren Protokolle zwischen Client und Server sowie zu verschiedenen persistenten Daten. Mit gcc-Optionen kann man angeben, dass die Gr\u00f6\u00dfe von wchar_t bei der Kompilierung ebenfalls 2 Bytes betragen soll, aber dann kann man die Verwendung der Standardbibliothek des Compilers vergessen, da sie glibc verwendet und diese wiederum f\u00fcr 4-Byte-wchar_t kompiliert ist. Weitere Gr\u00fcnde waren eine qualitativ hochwertigere Implementierung der Standardklassen, Unterst\u00fctzung von Hash-Tabellen und sogar die Emulation der Verschiebungssemantik innerhalb von Containern, die wir intensiv genutzt haben. Und ein weiterer Grund, wie man sagen k\u00f6nnte last but not least, war die Leistung von Zeichenfolgen. Wir hatten unsere eigene Klasse f\u00fcr Zeichenfolgen, da in Anbetracht der Spezifik unseres Softwares Zeichenoperationen sehr weit verbreitet sind und f\u00fcr uns kritische Bedeutung haben. <\/p>\n<p>Unsere Zeichenfolge basiert auf den Ideen zur Optimierung von Zeichenfolgen, die bereits Anfang der 2000er Jahre ge\u00e4u\u00dfert wurden <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\">von Andrei Alexandrescu<\/a><\/noindex>. Sp\u00e4ter, als Alexandrescu bei Facebook arbeitete, wurde auf seine Anregung hin eine Zeichenkette im Facebook-Engine verwendet, die nach \u00e4hnlichen Prinzipien funktionierte (siehe Bibliothek <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/folly\">folly<\/a><\/noindex>).<\/p>\n<p>. In unserer Zeichenkette kamen zwei Hauptoptimierungstechnologien zum Einsatz:<\/p>\n<ol>\n<li>F\u00fcr kurze Werte wird ein interner Puffer im Zeichenkettenobjekt verwendet (der keine zus\u00e4tzliche Speicheralokation ben\u00f6tigt).<\/li>\n<li>F\u00fcr alle anderen kommt die Mechanik <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>. Der Wert der Zeichenkette wird an einem Ort gespeichert, bei Zuweisung\/\u00c4nderung wird ein Referenzz\u00e4hler verwendet.<\/li>\n<\/ol>\n<p>\nUm die Kompilierungszeit der Plattform zu beschleunigen, haben wir die Stream-Implementierung aus unserer Version von STLPort ausgeschlossen (die wir nicht verwendet haben), was uns eine etwa 20%ige Verk\u00fcrzung der Kompilierungszeit brachte. Sp\u00e4ter mussten wir eingeschr\u00e4nkt verwenden <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Boost\">In den n\u00e4chsten zwei Monaten wird die genehmigte Spezifikation in der Phase der Dokumentenvorbereitung zur Ver\u00f6ffentlichung sein, in der an der redaktionellen Bearbeitung von Rechtschreibfehlern und Druckfehlern gearbeitet wird. Anfang November wird die resultierende Version des Dokuments zur Ver\u00f6ffentlichung an die ISO unter dem formalen Namen ISO\/IEC 14882:2020 gesendet. In der Zwischenzeit hat der Ausschuss bereits mit der Arbeit am n\u00e4chsten Standard C++23 (C++2b) begonnen und wird beim n\u00e4chsten virtuellen Treffen m\u00f6gliche<\/a><\/noindex>. Boost nutzt aktiv Streams, insbesondere in seinen Service-APIs (zum Beispiel zum Logging), weshalb wir es modifizieren mussten, indem wir die Nutzung von Streams ausschlossen. Das erschwerte uns den Umstieg auf neue Boost-Versionen. <\/p>\n<h3>Der dritte Weg<\/h3>\n<p>\nBei der Umstellung auf den C++14-Standard haben wir folgende Optionen in Betracht gezogen:<\/p>\n<ol>\n<li>Die von uns modifizierte STLPort auf den C++14-Standard zu portieren. Diese Option ist sehr kompliziert, da die Unterst\u00fctzung von STLPort 2010 eingestellt wurde und wir den gesamten Code selbst portieren m\u00fcssten.<\/li>\n<li>Wechsel zu einer anderen STL-Implementierung, die mit C++14 kompatibel ist. Es ist w\u00fcnschenswert, dass diese Implementierung unter Windows und Linux l\u00e4uft.<\/li>\n<li>Bei der Kompilierung jede OS einen im entsprechenden Compiler integrierten Bibliothek zu verwenden.<\/li>\n<\/ol>\n<p>\nDie erste Option wurde sofort aufgrund des zu gro\u00dfen Arbeitsaufwands abgelehnt.<\/p>\n<p>Wir dachten eine Zeit lang \u00fcber die zweite Option nach; als Kandidaten betrachteten wir <noindex><a rel=\"nofollow\" href=\"https:\/\/libcxx.llvm.org\/\">libc++<\/a><\/noindex>, aber zu diesem Zeitpunkt lief es nicht unter Windows. Um libc++ unter Windows zu portieren, m\u00fcssten wir viel Arbeit leisten \u2014 zum Beispiel alles, was mit Threads, Thread-Synchronisation und Atomicit\u00e4t zu tun hat, selbst zu schreiben, da in libc++ in diesen Bereichen <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/POSIX\">POSIX API<\/a><\/noindex>.<\/p>\n<p>verwendet wurde, und wir w\u00e4hlten den dritten Weg.<\/p>\n<h3>\u00dcbergang<\/h3>\n<p>\nWir mussten also die Nutzung von STLPort durch die Bibliotheken der entsprechenden Compiler ersetzen (Visual Studio 2015 f\u00fcr Windows, gcc 7 f\u00fcr Linux, clang 8 f\u00fcr macOS). <\/p>\n<p>Zum Gl\u00fcck wurde unser Code haupts\u00e4chlich nach den Richtlinien geschrieben und verwendete keine ausgekl\u00fcgelten Tricks, sodass die Migration auf die neuen Bibliotheken vergleichsweise reibungslos verlief, unterst\u00fctzt durch Skripte, die in den Quelldateien die Namen von Typen, Klassen, Namensr\u00e4umen und Includes ersetzten. Die Migration betraf 10.000 Quelldateien (von 14.000). wchar_t wurde durch char16_t ersetzt; wir haben uns entschieden, auf die Verwendung von wchar_t zu verzichten, da char16_t auf allen Betriebssystemen 2 Byte einnimmt und die Kompatibilit\u00e4t des Codes zwischen Windows und Linux nicht beeintr\u00e4chtigt.<\/p>\n<p>Es gab jedoch einige kleine Abenteuer. Zum Beispiel konnte im STLPort-Iterator implizit auf einen Zeiger auf ein Element gecastet werden, was an einigen Stellen in unserem Code verwendet wurde. In den neuen Bibliotheken war das nicht mehr m\u00f6glich, und diese Stellen mussten manuell analysiert und umgeschrieben werden. <\/p>\n<p>So, die Migration des Codes ist abgeschlossen, der Code wird f\u00fcr alle Betriebssysteme kompiliert. Es ist Zeit f\u00fcr die Tests. <\/p>\n<p>Die Tests nach der Migration zeigten einen Leistungsabfall (stellenweise um 20-30%) und einen Anstieg des Speicherverbrauchs (um 10-15%) im Vergleich zur alten Version des Codes. Dies war unter anderem auf die suboptimale Handhabung von Standardstrings zur\u00fcckzuf\u00fchren. Deshalb mussten wir erneut unsere eigene, leicht \u00fcberarbeitete String-Implementierung verwenden. <\/p>\n<p>Au\u00dferdem stellte sich eine interessante Eigenschaft der Container-Implementierungen in den eingebetteten Bibliotheken heraus: Leere (ohne Elemente) std::map und std::set aus den eingebetteten Bibliotheken allozieren Speicher. In unserem Code wurden aufgrund der Implementierungsmerkmale an einigen Stellen viele leere Container dieses Typs erstellt. Die Standardcontainer allozieren wenig Speicher, nur f\u00fcr ein Wurzel-Element, aber f\u00fcr uns war das kritisch \u2013 in einigen Szenarien fiel die Leistung sp\u00fcrbar ab und der Speicherverbrauch stieg (im Vergleich zu STLPort). Daher haben wir diese beiden Typen von Containern aus den eingebetteten Bibliotheken in unserem Code durch ihre Implementierung von Boost ersetzt, bei der diese Container nicht diese Besonderheit hatten, und das l\u00f6ste das Problem mit der Verlangsamung und dem erh\u00f6hten Speicherverbrauch.<\/p>\n<p>Wie h\u00e4ufig nach umfangreichen \u00c4nderungen in gro\u00dfen Projekten, hatte die erste Iteration des Quellcodes einige Probleme, und hier war insbesondere die Unterst\u00fctzung f\u00fcr Debug-Iteratoren in der Windows-Implementierung sehr hilfreich. Schritt f\u00fcr Schritt kamen wir voran, und bis zum Fr\u00fchling 2017 (Version 8.3.11 1C:Enterprise) war die Migration abgeschlossen. <\/p>\n<h3>Ergebnisse<\/h3>\n<p>\nDer \u00dcbergang zu C++14 dauerte etwa 6 Monate. Den Gro\u00dfteil der Zeit arbeitete ein sehr hochqualifizierter Entwickler allein am Projekt, und in der finalen Phase kamen Vertreter der Teams hinzu, die f\u00fcr bestimmte Bereiche zust\u00e4ndig sind \u2014 UI, Cluster-Server, Entwicklungs- und Verwaltungstools usw.<\/p>\n<p>Der \u00dcbergang hat unsere Arbeit an der Migration zu den neuesten Versionen des Standards erheblich erleichtert. So wurde die Version 1C:Unternehmen 8.3.14 (in Entwicklung, die Ver\u00f6ffentlichung ist f\u00fcr Anfang n\u00e4chsten Jahres geplant) bereits auf den Standard <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B17\">C++17<\/a><\/noindex>. <\/p>\n<p>Nach der Migration hatten die Entwickler mehr M\u00f6glichkeiten. Fr\u00fcher hatten wir unsere angepasste Version der STL und einen Namensraum std, jetzt befinden sich im Namensraum std die Standardklassen aus den Standardbibliotheken des Compilers, im Namensraum stdx \u2013 unsere, f\u00fcr unsere Aufgaben optimierten Strings und Container, und in Boost \u2013 die neueste Version von Boost. Der Entwickler verwendet die Klassen, die optimal f\u00fcr die L\u00f6sung seiner Aufgaben geeignet sind. <\/p>\n<p>Auch die \"native\" Implementierung von Move-Konstruktoren (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/move_constructor\">move constructors<\/a><\/noindex>) f\u00fcr eine Reihe von Klassen hilft bei der Entwicklung. Wenn eine Klasse einen Move-Konstruktor hat und diese Klasse in einen Container eingef\u00fcgt wird, optimiert die STL das Kopieren der Elemente innerhalb des Containers (zum Beispiel, wenn der Container erweitert wird und die Kapazit\u00e4t ver\u00e4ndert und der Speicher neu zugewiesen werden muss). <\/p>\n<h3>Ein Wermutstropfen<\/h3>\n<p>\nDas vielleicht unangenehmste (aber nicht kritische) Ergebnis der Migration \u2014 wir sind auf ein erh\u00f6htes Volumen gesto\u00dfen <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\">obj-Dateien<\/a><\/noindex>, und das vollst\u00e4ndige Build-Ergebnis mit allen Zwischenfiles ben\u00f6tigt nun 60 \u2013 70 GB. Dieses Verhalten h\u00e4ngt mit den Eigenschaften moderner Standardbibliotheken zusammen, die weniger kritisch mit dem Volumen der generierten Hilfsdateien umgehen. Dies hat keinen Einfluss auf die Funktion des kompilierten Programms, verursacht jedoch einige Unannehmlichkeiten in der Entwicklung, insbesondere erh\u00f6ht es die Kompilierungszeit. Auch die Anforderungen an den freien Speicherplatz auf den Build-Servern und den Maschinen der Entwickler steigen. Unsere Entwickler arbeiten parallel an mehreren Versionen der Plattform, und hunderte Gigabyte an Zwischenfiles schaffen manchmal Schwierigkeiten in der Arbeit. Das Problem ist unangenehm, aber nicht kritisch, eine L\u00f6sung haben wir vorerst aufgeschoben. Eine der L\u00f6sungen, die wir in Betracht ziehen, ist die Technik <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Single_Compilation_Unit\">unity build<\/a><\/noindex> (sie wird unter anderem von Google bei der Entwicklung des Browsers Chrome verwendet).<br \/>\n<br \/>Quelle: <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.1.1 - 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\/de\/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.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\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\/de\/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\udd47Wie wir 10 Millionen Zeilen C++-Code auf den Standard C++14 (und dann auf C++17) \u00fcbersetzt haben | ProHoster","description":"Vor einiger Zeit (Herbst 2016) stellte sich im Entwicklungsteam bei der Entwicklung einer neuen Version der technologischen Plattform 1C:Unternehmen die Frage nach der Unterst\u00fctzung des neuen Standards","canonical_url":"https:\/\/prohoster.info\/de\/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":"de_DE","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\/de\/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\/de\/wp-json\/wp\/v2\/posts\/32466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=32466"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/32466\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/24270"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=32466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=32466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=32466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}