{"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\/sv\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17","title":{"rendered":"Hur vi \u00f6versatte 10 miljoner rader C++-kod till standard C++14 (och sedan till C++17)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>F\u00f6r en tid sedan (h\u00f6sten 2016), n\u00e4r vi utvecklade en ny version av teknologiplattformen 1C:Enterprise, kom fr\u00e5gan om att st\u00f6dja den nya standarden upp inom utvecklingsteamet. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B14\">C++14<\/a><\/noindex> i v\u00e5r kod. \u00d6verg\u00e5ngen till den nya standarden, som vi antog, skulle l\u00e5ta oss skriva m\u00e5nga saker mer elegant, enklare och mer p\u00e5litligt, och f\u00f6renkla underh\u00e5ll och support av koden. Det kan verka ointressant i \u00f6vers\u00e4ttning, om det inte vore f\u00f6r storleken p\u00e5 kodbasen och specifika egenskaper i v\u00e5r kod.<\/p>\n<p>F\u00f6r dem som inte vet, \u00e4r 1C:Enterprise en milj\u00f6 f\u00f6r snabb utveckling av plattformsoberoende aff\u00e4rsapplikationer och en runtime f\u00f6r att k\u00f6ra dem p\u00e5 olika operativsystem och databashanterare. I stora drag inneh\u00e5ller produkten f\u00f6ljande:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000885.htm\">Klass av applikationsservrar<\/a><\/noindex>, fungerar p\u00e5 Windows och Linux<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000124.htm\">Klient<\/a><\/noindex>, som kommunicerar med servern via http(s) eller via egen bin\u00e4r protokoll, fungerar p\u00e5 Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/315414\/\">Webbkund<\/a><\/noindex>, som fungerar i webbl\u00e4sarna Chrome, Internet Explorer, Microsoft Edge, Firefox, Safari (skriven i JavaScript)<\/li>\n<li>Utvecklingsmilj\u00f6 (<noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000008.htm\">Konfigurator<\/a><\/noindex>), fungerar p\u00e5 Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000813.htm\">Administrationsverktyg<\/a><\/noindex> f\u00f6r applikationsservrar, fungerar p\u00e5 Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/wonderland.v8.1c.ru\/blog\/mobilnyy-klient\/\">Mobilklient<\/a><\/noindex>, ansluter till servern via http(s), fungerar p\u00e5 mobila enheter som k\u00f6r Android, iOS, Windows<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/283198\/\">Mobilplattform<\/a><\/noindex> \u2014 ett ramverk f\u00f6r att skapa offline-mobilapplikationer med synkroniseringsm\u00f6jligheter, fungerande p\u00e5 Android, iOS, Windows<\/li>\n<li>Utvecklingsmilj\u00f6 <noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/IDE\/\">1C:Enterprise Utvecklingsverktyg<\/a><\/noindex>, skriven i Java<\/li>\n<li>Servern <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/422903\/\">Interaktionssystem<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nVi str\u00e4var efter att maximalt skriva en enda kod f\u00f6r olika operativsystem \u2014 kodbasen f\u00f6r servern \u00e4r gemensam till 99%, klienten till ungef\u00e4r 95%. Teknologiplattformen 1C:Enterprise \u00e4r huvudsakligen skriven i C++ och nedan f\u00f6ljer ungef\u00e4rliga egenskaper f\u00f6r koden:<\/p>\n<ul>\n<li>10 miljoner rader C++ kod,<\/li>\n<li>14 000 filer,<\/li>\n<li>60 000 klasser,<\/li>\n<li>en halv miljon metoder.<\/li>\n<\/ul>\n<p>\nOch hela detta system m\u00e5ste \u00f6vers\u00e4ttas till C++14. Idag kommer vi att ber\u00e4tta om hur vi gjorde detta och vilka utmaningar vi st\u00f6tte p\u00e5 under processen.<\/p>\n<p><img decoding=\"async\" alt=\"Hur vi \u00f6versatte 10 miljoner rader C++-kod till standard C++14 (och sedan till 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>Disclaimer<\/h3>\n<p>\nDet som skrivs nedan om l\u00e5ngsamt\/snabbt arbete och (inte) stort minnesanv\u00e4ndande av standardklassimplementationer i olika bibliotek g\u00e4ller ENDAST f\u00f6r OSS. Det \u00e4r fullt m\u00f6jligt att de standardimplementationer som finns passar b\u00e4st f\u00f6r dina behov. Vi utgick ifr\u00e5n v\u00e5ra behov: vi tog typiska data fr\u00e5n v\u00e5ra kunder, k\u00f6rde typiska scenarier p\u00e5 dem, tittade p\u00e5 prestanda, minnesanv\u00e4ndning osv., och analyserade om resultaten uppfyllde v\u00e5ra och v\u00e5ra kunders krav eller inte. Och vi agerade beroende p\u00e5 det.<\/p>\n<h3>Vad vi hade<\/h3>\n<p>\nInitialt skrev vi koden f\u00f6r plattformen 1C:Enterprise 8 i Microsoft Visual Studio. Projektet b\u00f6rjade i b\u00f6rjan av 2000-talet och vi hade bara en version f\u00f6r Windows. Naturligtvis har koden utvecklats mycket sedan dess, m\u00e5nga mekanismer har skrivits om helt. Men koden skrevs enligt standar 1998, s\u00e5 vi hade till exempel h\u00f6gra vinkelparenteser separerade med mellanslag f\u00f6r att kompileringen skulle g\u00e5 igenom, s\u00e5 h\u00e4r:<\/p>\n<pre><code class=\"cpp\">vector&lt;vector &gt; IntV;<\/code><\/pre>\n<p>\n\u00c5r 2006, med lanseringen av plattformversion 8.1, b\u00f6rjade vi st\u00f6dja Linux och \u00f6vergick till ett tredjeparts standardbibliotek <noindex><a rel=\"nofollow\" href=\"http:\/\/www.stlport.org\/\">STLPort<\/a><\/noindex>. En av anledningarna till \u00f6verg\u00e5ngen var arbetet med breda str\u00e4ngar. I v\u00e5r kod anv\u00e4nder vi \u00f6verallt std::wstring, som baseras p\u00e5 typen wchar_t. Dess storlek i Windows \u00e4r 2 byte, men i Linux \u00e4r den som standard 4 byte. Detta ledde till inkompatibilitet av v\u00e5ra bin\u00e4ra protokoll mellan klient och server, samt olika permanenta data. Med gcc:s alternativ kan man ange att storleken p\u00e5 wchar_t under kompilering ocks\u00e5 ska vara 2 byte, men d\u00e5 f\u00e5r man gl\u00f6mma att anv\u00e4nda standardbiblioteket fr\u00e5n kompilatorn, eftersom det anv\u00e4nder glibc, som i sin tur \u00e4r kompilera f\u00f6r 4-byte wchar_t. Andra anledningar var en mer kvalitativ implementation av standardklasser, st\u00f6d f\u00f6r hash-tabeller och till och med emulering av flyttsemantik inom containrar, vilket vi anv\u00e4nde flitigt. Och en annan anledning, som man s\u00e4ger, last but not least, var prestandan hos str\u00e4ngarna. Vi hade v\u00e5r egen klass f\u00f6r str\u00e4ngar, eftersom str\u00e4ngoperationer anv\u00e4nds mycket brett i v\u00e5r mjukvaras specifik och \u00e4r kritiska f\u00f6r oss. <\/p>\n<p>V\u00e5r str\u00e4ng \u00e4r baserad p\u00e5 id\u00e9er om optimering av str\u00e4ngar, som formulerades redan i b\u00f6rjan av 2000-talet <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\">Andrei Alexandrescu<\/a><\/noindex>. Senare, n\u00e4r Alexandrescu arbetade p\u00e5 Facebook, anv\u00e4ndes en rad i Facebooks motor p\u00e5 liknande principer (se biblioteket <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/folly\">folly<\/a><\/noindex>).<\/p>\n<p>. I v\u00e5r rad anv\u00e4ndes tv\u00e5 huvudsakliga optimeringstekniker:<\/p>\n<ol>\n<li>F\u00f6r korta v\u00e4rden anv\u00e4nds en intern buffert i sj\u00e4lva str\u00e4ngobjektet (som inte kr\u00e4ver extra minnesallokering).<\/li>\n<li>F\u00f6r alla andra anv\u00e4nds mekanismen <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>. V\u00e4rdet av str\u00e4ngen lagras p\u00e5 ett st\u00e4lle, och vid tilldelning\/modifiering anv\u00e4nds en referensr\u00e4knare.<\/li>\n<\/ol>\n<p>\nF\u00f6r att p\u00e5skynda kompileringen av plattformen utesl\u00f6t vi stream-implementeringen fr\u00e5n v\u00e5r version av STLPort (som vi inte anv\u00e4nde), vilket gav oss cirka 20 % snabbare kompilering. Som en f\u00f6ljd av detta var vi tvungna att anv\u00e4nda <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Boost\">Boost<\/a><\/noindex>. Boost anv\u00e4nder aktivt stream, s\u00e4rskilt i sina tj\u00e4nst-API:er (till exempel f\u00f6r loggning), s\u00e5 vi var tvungna att modifiera det genom att utesluta anv\u00e4ndningen av stream. Detta gjorde det i sin tur sv\u00e5rare f\u00f6r oss att migrera till nya versioner av Boost. <\/p>\n<h3>Det tredje alternativet<\/h3>\n<p>\nVid \u00f6verg\u00e5ngen till standard C++14 \u00f6verv\u00e4gde vi f\u00f6ljande alternativ:<\/p>\n<ol>\n<li>Att bygga upp v\u00e5r modifierade STLPort p\u00e5 standard C++14. Detta alternativ \u00e4r mycket komplicerat, eftersom st\u00f6det f\u00f6r STLPort upph\u00f6rde 2010, och vi skulle beh\u00f6va lyfta hela dess kod sj\u00e4lva.<\/li>\n<li>\u00d6verg\u00e5ng till en annan STL-implementation som \u00e4r kompatibel med C++14. Det \u00e4r mycket \u00f6nskv\u00e4rt att denna implementation fungerar p\u00e5 Windows och Linux.<\/li>\n<li>Att anv\u00e4nda den inbyggda biblioteket i respektive kompilator vid kompilering f\u00f6r varje OS.<\/li>\n<\/ol>\n<p>\nDet f\u00f6rsta alternativet avf\u00e4rdades genast p\u00e5 grund av den alltf\u00f6r stora arbetsm\u00e4ngden.<\/p>\n<p>Vi funderade ett tag p\u00e5 det andra alternativet; som kandidat \u00f6verv\u00e4gde vi <noindex><a rel=\"nofollow\" href=\"https:\/\/libcxx.llvm.org\/\">libc++<\/a><\/noindex>, men den fungerade vid den tidpunkten inte p\u00e5 Windows. F\u00f6r att porta libc++ till Windows skulle det kr\u00e4vas en hel del arbete \u2014 till exempel skulle vi beh\u00f6va skriva allt som r\u00f6r tr\u00e5dar, tr\u00e5d-synkronisering och atomaritet, eftersom libc++ anv\u00e4nde <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/POSIX\">POSIX API<\/a><\/noindex>.<\/p>\n<p>Och vi valde det tredje alternativet.<\/p>\n<h3>\u00d6verg\u00e5ngen<\/h3>\n<p>\nS\u00e5 vi skulle ers\u00e4tta anv\u00e4ndningen av STLPort med biblioteken fr\u00e5n respektive kompilatorer (Visual Studio 2015 f\u00f6r Windows, gcc 7 f\u00f6r Linux, clang 8 f\u00f6r macOS). <\/p>\n<p>Lyckligtvis skrevs v\u00e5r kod huvudsakligen enligt riktlinjerna och anv\u00e4nde inte n\u00e5gra kluriga tricks, s\u00e5 migreringen till de nya biblioteken gick ganska smidigt, med hj\u00e4lp av skript som ersatte typ-, klass-, namnrymds- och inkluderingsnamn i k\u00e4llfilerna. Migreringen ber\u00f6rde 10 000 k\u00e4llfiler (av 14 000). wchar_t ersattes med char16_t; vi beslutade att avst\u00e5 fr\u00e5n att anv\u00e4nda wchar_t, eftersom char16_t tar 2 byte p\u00e5 alla operativsystem och inte st\u00f6r kodens kompatibilitet mellan Windows och Linux.<\/p>\n<p>Det blev dock inte utan sm\u00e5 \u00e4ventyr. Till exempel kunde man i STLPort implicit typkonvertera en iterator till en pekare p\u00e5 ett element, och p\u00e5 vissa st\u00e4llen i v\u00e5r kod anv\u00e4ndes detta. I de nya biblioteken gick det inte l\u00e4ngre att g\u00f6ra s\u00e5, och dessa st\u00e4llen fick vi analysera och skriva om manuellt. <\/p>\n<p>S\u00e5, kodmigreringen \u00e4r avslutad, koden kompileras f\u00f6r alla operativsystem. Det \u00e4r dags f\u00f6r tester. <\/p>\n<p>Tester efter \u00f6verg\u00e5ngen visade en nedg\u00e5ng i prestanda (i vissa fall upp till 20-30%) och en \u00f6kning av minnesanv\u00e4ndningen (upp till 10-15%) j\u00e4mf\u00f6rt med den gamla kodversionen. Detta berodde delvis p\u00e5 den suboptimala hanteringen av standardstr\u00e4ngar. D\u00e4rf\u00f6r var vi tvungna att \u00e5terigen anv\u00e4nda v\u00e5r egen str\u00e4ng, n\u00e5got modifierad. <\/p>\n<p>Det avsl\u00f6jades ocks\u00e5 en intressant egenskap hos implementeringen av beh\u00e5llare i inbyggda bibliotek: tomma (utan element) std::map och std::set fr\u00e5n de inbyggda biblioteken allokerar minne. Och i vissa delar av v\u00e5r kod skapas det ganska m\u00e5nga tomma beh\u00e5llare av denna typ p\u00e5 grund av implementationens s\u00e4rdrag. De standardbeh\u00e5llare som allokerar minne g\u00f6r det lite, f\u00f6r ett rot-element, men f\u00f6r oss blev detta kritiskt \u2013 under flera scenarier minskade vi prestandan avsev\u00e4rt och \u00f6kade minnesanv\u00e4ndningen (j\u00e4mf\u00f6rt med STLPort). D\u00e4rf\u00f6r ersatte vi dessa tv\u00e5 typer av beh\u00e5llare fr\u00e5n de inbyggda biblioteken med deras implementation fr\u00e5n Boost, d\u00e4r dessa beh\u00e5llare inte hade denna egenskap, och det l\u00f6ste problemet med nedg\u00e5ng och \u00f6kad minnesanv\u00e4ndning.<\/p>\n<p>Som det ofta \u00e4r fallet efter omfattande f\u00f6r\u00e4ndringar i stora projekt fungerade f\u00f6rsta iterationen av k\u00e4llkoden inte utan problem, och h\u00e4r blev st\u00f6det f\u00f6r debuggenomg\u00e5ngar i Windows-implementationen mycket anv\u00e4ndbart. Steg f\u00f6r steg gick vi fram\u00e5t, och i v\u00e5r 2017 (version 8.3.11 fr\u00e5n 1C: Enterprise) var migreringen avslutad. <\/p>\n<h3>Sammanfattning<\/h3>\n<p>\n\u00d6verg\u00e5ngen till standard C++14 tog oss cirka 6 m\u00e5nader. Under st\u00f6rre delen av projektet arbetade en (men mycket kvalificerad) utvecklare ensam, och i den avslutande fasen ansl\u00f6t sig representanter fr\u00e5n teamen ansvariga f\u00f6r specifika omr\u00e5den \u2013 UI, kluster servrar, utvecklings- och administreringsverktyg osv.<\/p>\n<p>\u00d6verg\u00e5ngen har kraftigt f\u00f6renklat v\u00e5rt arbete med att migrera till de nyaste versionerna av standarden. S\u00e5ledes \u00e4r version 1C:Enterprise 8.3.14 (under utveckling, release planerad till b\u00f6rjan av n\u00e4sta \u00e5r) redan \u00f6versatt till standarden <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B17\">C++17<\/a><\/noindex>. <\/p>\n<p>Efter migreringen har utvecklarna f\u00e5tt fler m\u00f6jligheter. F\u00f6rr hade vi v\u00e5r egen modifierade version av STL och ett namnomr\u00e5de std, men nu inneh\u00e5ller namnomr\u00e5det std standardklasser fr\u00e5n kompilatorns inbyggda bibliotek, i namnomr\u00e5det stdx \u2013 v\u00e5ra, optimerade f\u00f6r v\u00e5ra uppgifter, str\u00e4ngar och beh\u00e5llare, i boost \u2013 den senaste versionen av boost. Utvecklaren anv\u00e4nder de klasser som optimalt passar f\u00f6r att l\u00f6sa hans uppgifter. <\/p>\n<p>Den inbyggda implementeringen av flyttkonstrukt\u00f6rer hj\u00e4lper ocks\u00e5 till i utvecklingen (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/move_constructor\">move constructors<\/a><\/noindex>) f\u00f6r ett antal klasser. Om en klass har en flyttkonstrukt\u00f6r och denna klass placeras i en beh\u00e5llare, s\u00e5 optimerar STL kopieringen av element inuti beh\u00e5llaren (till exempel n\u00e4r beh\u00e5llaren expanderar och kapaciteten beh\u00f6ver \u00e4ndras och minnet m\u00e5ste allokeras p\u00e5 nytt). <\/p>\n<h3>En sked te<\/h3>\n<p>\nDet som nog \u00e4r det mest obehagliga (men inte kritiska) resultatet av migreringen \u2013 vi har st\u00f6tt p\u00e5 en \u00f6kning av m\u00e4ngden <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-filer<\/a><\/noindex>, och det totala resultatet av bygget med alla mellanliggande filer har blivit 60\u201370 GB. Detta beteende \u00e4r relaterat till egenskaperna hos moderna standardbibliotek, som blivit mindre kritiska n\u00e4r det g\u00e4ller m\u00e4ngden genererade hj\u00e4lpfiler. Detta p\u00e5verkar inte arbetet med den kompilerade applikationen, men medf\u00f6r en rad ol\u00e4genheter i utvecklingen, s\u00e4rskilt \u00f6kar compilationstiden. Kraven p\u00e5 ledigt diskutrymme p\u00e5 byggservrar och utvecklarens maskiner har ocks\u00e5 \u00f6kat. V\u00e5ra utvecklare arbetar parallellt med flera versioner av plattformen, och hundratals gigabyte mellanliggande filer skapar ibland sv\u00e5righeter i arbetet. Problemet \u00e4r obehagligt, men inte kritiskt, och vi har f\u00f6r tillf\u00e4llet skjutit upp l\u00f6sningen. Som ett av alternativen f\u00f6r att l\u00f6sa det \u00f6verv\u00e4ger vi tekniken <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Single_Compilation_Unit\">unity build<\/a><\/noindex> (det, bland annat, anv\u00e4nder Google vid utvecklingen av webbl\u00e4saren Chrome).<br \/>\n<br \/>K\u00e4lla: <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.4 - 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\/sv\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\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\/sv\/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\udd47Hur vi \u00f6versatte 10 miljoner rader C++-kod till standard C++14 (och sedan till C++17) | ProHoster","description":"F\u00f6r en tid sedan (h\u00f6sten 2016), n\u00e4r vi utvecklade en ny version av teknologiplattformen 1C:Enterprise, kom fr\u00e5gan om att st\u00f6dja den nya standarden upp inom utvecklingsteamet.","canonical_url":"https:\/\/prohoster.info\/sv\/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":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/32466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=32466"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/32466\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/24270"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=32466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=32466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=32466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}