{"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\/ro\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17","title":{"rendered":"Cum am tradus 10 milioane de linii de cod C++ la standardul C++14 (\u0219i apoi la C++17)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Cu ceva vreme \u00een urm\u0103 (toamna anului 2016), \u00een timpul dezvolt\u0103rii unei noi versiuni a platformei tehnologice 1C:Enterprise, echipa de dezvoltare a ridicat \u00eentrebarea despre suportul pentru noul standard <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B14\">C++14<\/a><\/noindex> \u00een codul nostru. Tranzi\u021bia la noul standard, a\u0219a cum am presupus, ne-ar permite s\u0103 scriem multe lucruri mai elegant, mai simplu \u0219i mai sigur, simplific\u00e2nd \u00eentre\u021binerea \u0219i suportul codului. \u0218i, aparent, nu este nimic extraordinar \u00een traducere, dac\u0103 nu ar fi dimensiunile bazei de cod \u0219i caracteristicile specifice ale codului nostru.<\/p>\n<p>Pentru cei care nu \u0219tiu, 1C:Enterprise este un mediu pentru dezvoltarea rapid\u0103 de aplica\u021bii de afaceri multiplatform\u0103 \u0219i un runtime pentru execu\u021bia acestora \u00een diferite OS-uri \u0219i SGBD-uri. \u00cen linii generale, produsul include:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000885.htm\">Un cluster de servere aplica\u021bii<\/a><\/noindex>, care func\u021bioneaz\u0103 pe Windows \u0219i Linux<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000124.htm\">Clientului<\/a><\/noindex>, comunic\u00e2nd cu serverul prin http(s) sau prin propriul protocol binar, func\u021bioneaz\u0103 pe Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/315414\/\">Client web<\/a><\/noindex>, care ruleaz\u0103 \u00een browserele Chrome, Internet Explorer, Microsoft Edge, Firefox, Safari (scris \u00een JavaScript)<\/li>\n<li>Mediul de dezvoltare (<noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000008.htm\">Configurator<\/a><\/noindex>), care func\u021bioneaz\u0103 pe Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000813.htm\">Instrumentele de administrare<\/a><\/noindex> serverelor aplica\u021bii, care func\u021bioneaz\u0103 pe Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/wonderland.v8.1c.ru\/blog\/mobilnyy-klient\/\">Clientul mobil<\/a><\/noindex>, conect\u00e2ndu-se la server prin http(s), func\u021bioneaz\u0103 pe dispozitive mobile cu Android, iOS, Windows<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/283198\/\">Platforma mobil\u0103<\/a><\/noindex> \u2014 un framework pentru crearea aplica\u021biilor mobile offline cu capacitatea de sincronizare, care func\u021bioneaz\u0103 pe Android, iOS, Windows<\/li>\n<li>Mediul de dezvoltare <noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/IDE\/\">Uneltele de dezvoltare 1C:Enterprise<\/a><\/noindex>, scris \u00een Java<\/li>\n<li>Server <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/422903\/\">Sisteme de Interac\u021biune<\/a><\/noindex><\/li>\n<\/ul>\n<p>\n\u00cencerc\u0103m s\u0103 scriem c\u00e2t mai mult un singur cod pentru diferite OS-uri \u2014 baza de cod a serverului este comun\u0103 \u00een propor\u021bie de 99%, iar cea a clientului \u2014 \u00een propor\u021bie de aproximativ 95%. Platforma tehnologic\u0103 1C:Enterprise este predominant scris\u0103 \u00een C++ \u0219i mai jos sunt furnizate caracteristicile aproximative ale codului:<\/p>\n<ul>\n<li>10 milioane de linii de cod C++,<\/li>\n<li>14 mii de fi\u0219iere,<\/li>\n<li>60 mii de clase,<\/li>\n<li>o jum\u0103tate de milion de metode.<\/li>\n<\/ul>\n<p>\n\u0218i tot acest lucru a trebuit tradus pe C++14. Despre cum am f\u0103cut asta \u0219i cu ce ne-am confruntat \u00een proces, vom vorbi ast\u0103zi.<\/p>\n<p><img decoding=\"async\" alt=\"Cum am tradus 10 milioane de linii de cod C++ la standardul C++14 (\u0219i apoi la 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>Declinarea responsabilit\u0103\u021bii<\/h3>\n<p>\nTot ce este scris mai jos despre viteza lent\u0103\/rapid\u0103 de func\u021bionare, consumul (ne)mic de memorie al implement\u0103rilor standard \u00een diverse biblioteci \u00eenseamn\u0103 un singur lucru: este valabil PENTRU NOI. Este posibil ca implement\u0103rile standard s\u0103 fie cele mai potrivite pentru sarcinile dumneavoastr\u0103. Noi ne-am bazat pe propriile noastre sarcini: am luat datele tipice pentru clien\u021bii no\u0219tri, le-am rulat prin scenarii tipice, am analizat performan\u021ba, volumul de memorie consumat etc., \u0219i am evaluat dac\u0103 rezultatele ne satisfac pe noi \u0219i pe clien\u021bii no\u0219tri sau nu. \u0218i ne-am comportat \u00een func\u021bie de asta.<\/p>\n<h3>Ce am avut<\/h3>\n<p>\nIni\u021bial, am scris codul platformei 1C:Enterprise 8 \u00een Microsoft Visual Studio. Proiectul a \u00eenceput la \u00eenceputul anilor 2000 \u0219i aveam doar o versiune pentru Windows. Fire\u0219te, de atunci, codul s-a dezvoltat activ, multe mecanisme fiind complet rescrise. Dar codul a fost scris conform standardului din 1998, iar, de exemplu, parantezele drepte erau separate prin spa\u021bii pentru a trece cu succes compilarea, astfel:<\/p>\n<pre><code class=\"cpp\">vector&lt;vector&gt; IntV;<\/code><\/pre>\n<p>\n\u00cen 2006, odat\u0103 cu lansarea versiunii platformei 8.1, am \u00eenceput s\u0103 suport\u0103m Linux \u0219i am trecut la o bibliotec\u0103 standard extern\u0103 <noindex><a rel=\"nofollow\" href=\"http:\/\/www.stlport.org\/\">STLPort<\/a><\/noindex>. Una dintre motivele acestei tranzi\u021bii a fost lucrul cu \u0219iruri largi. \u00cen codul nostru folosim pe scar\u0103 larg\u0103 std::wstring, bazat pe tipul wchar_t. Dimensiunea sa \u00een Windows este de 2 octe\u021bi, iar \u00een Linux, implicit, de 4 octe\u021bi. Acest lucru ducea la incompatibilit\u0103\u021bi \u00eentre protocoalele noastre binare \u00eentre client \u0219i server, precum \u0219i diverse date persistente. Op\u021biunile gcc pot specifica ca dimensiunea wchar_t la compilare s\u0103 fie tot de 2 octe\u021bi, dar \u00een acest caz, trebuie s\u0103 renun\u021b\u0103m la utilizarea bibliotecii standard a compilatorului, deoarece aceasta folose\u0219te glibc, care la r\u00e2ndul s\u0103u este compilat\u0103 pentru wchar_t de 4 octe\u021bi. Alte motive au fost o implementare mai bun\u0103 a claselor standard, suportul pentru tabele de dispersie \u0219i chiar emularea semanticii mut\u0103rii \u00een interiorul containerelor, pe care noi le-am utilizat activ. \u0218i un alt motiv, cum s-ar spune, ultimul dar nu cel din urm\u0103, a fost performan\u021ba \u0219irurilor. Aveam propria clas\u0103 pentru \u0219iruri, deoarece din cauza specificului software-ului nostru, opera\u021biile pe \u0219iruri sunt utilizate foarte pe scar\u0103 larg\u0103 \u0219i acest lucru este critic pentru noi. <\/p>\n<p>\u0218irul nostru este bazat pe ideile de optimizare a \u0219irurilor, exprimate \u00eenc\u0103 la \u00eenceputul anilor 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\">de Andrei Alexandrescu<\/a><\/noindex>. Ulterior, c\u00e2nd Alexandrescu lucra la Facebook, la propunerea lui a fost folosit\u0103 \u00een motorul Facebook o linie care func\u021biona pe principii asem\u0103n\u0103toare (vezi biblioteca <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/folly\">folly<\/a><\/noindex>).<\/p>\n<p>\u00cen linia noastr\u0103 au fost folosite dou\u0103 tehnologii principale de optimizare:<\/p>\n<ol>\n<li>Pentru valori scurte se utilizeaz\u0103 un buffer intern \u00een obiectul string (care nu necesit\u0103 alocare suplimentar\u0103 de memorie).<\/li>\n<li>Pentru toate celelalte se folose\u0219te mecanica <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>. Valoarea stringului este stocat\u0103 \u00eentr-un singur loc, la atribuirea\/modificarea sa se utilizeaz\u0103 un contor de referin\u021be.<\/li>\n<\/ol>\n<p>\nPentru a accelera compilarea platformei, am exclus din varianta noastr\u0103 STLPort implementarea stream (pe care nu o foloseam), acest lucru ne-a oferit un avantaj de aproximativ 20% la compilare. Ulterior, a trebuit s\u0103 folosim \u00een mod restric\u021bionat <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Boost\">Boost<\/a><\/noindex>. Boost folose\u0219te \u00een mod activ stream, \u00een special \u00een API-urile sale de servicii (de exemplu, pentru logare), a\u0219a c\u0103 a trebuit s\u0103-l modific\u0103m, excluz\u00e2nd utilizarea stream-ului. Acest lucru, la r\u00e2ndul s\u0103u, ne-a \u00eengreunat tranzi\u021bia c\u0103tre versiunile noi de Boost. <\/p>\n<h3>A treia cale<\/h3>\n<p>\nAtunci c\u00e2nd am trecut la standardul C++14, am considerat urm\u0103toarele op\u021biuni:<\/p>\n<ol>\n<li>S\u0103 ridic\u0103m STLPort modificat pe standardul C++14. Op\u021biunea este foarte complicat\u0103, deoarece suportul pentru STLPort a fost oprit \u00een 2010 \u0219i ar fi trebuit s\u0103 ridic\u0103m tot codul noi \u00een\u0219ine.<\/li>\n<li>Trecerea la o alt\u0103 implementare STL, compatibil\u0103 cu C++14. Ideal ar fi ca aceast\u0103 implementare s\u0103 fie disponibil\u0103 pentru Windows \u0219i Linux.<\/li>\n<li>S\u0103 folosim la compilare biblioteca \u00eencorporat\u0103 \u00een fiecare compilator corespunz\u0103tor pentru fiecare sistem de operare.<\/li>\n<\/ol>\n<p>\nPrima op\u021biune a fost respins\u0103 imediat din cauza volumului prea mare de munc\u0103.<\/p>\n<p>Ne-am g\u00e2ndit o vreme la a doua op\u021biune; ca \u0219i candidat, am luat \u00een considerare <noindex><a rel=\"nofollow\" href=\"https:\/\/libcxx.llvm.org\/\">libc++<\/a><\/noindex>, dar aceasta nu func\u021biona pe Windows \u00een acel moment. Pentru a porta libc++ pe Windows, ar fi fost necesare multe munc\u0103 \u2014 de exemplu, s\u0103 scriem noi tot ce \u021bine de thread-uri, sincronizarea thread-urilor \u0219i atomicitate, deoarece \u00een libc++ \u00een aceste domenii era folosit <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/POSIX\">POSIX API<\/a><\/noindex>.<\/p>\n<p>\u0218i am ales a treia cale.<\/p>\n<h3>Trecerea<\/h3>\n<p>\nA\u0219adar, trebuia s\u0103 \u00eenlocuim utilizarea STLPort cu bibliotecile corespunz\u0103toare ale compilatoarelor (Visual Studio 2015 pentru Windows, gcc 7 pentru Linux, clang 8 pentru macOS). <\/p>\n<p>Din fericire, codul nostru a fost scris \u00een principal conform liniilor directoare \u0219i nu a folosit trucuri elaborate, astfel c\u0103 migrarea c\u0103tre biblioteci noi s-a desf\u0103\u0219urat relativ lin, cu ajutorul scripturilor care \u00eenlocuiau \u00een fi\u0219ierele surs\u0103 numele tipurilor, claselor, spa\u021biilor de nume \u0219i includerilor. Migrarea a afectat 10.000 de fi\u0219iere surs\u0103 (din 14.000). wchar_t a fost \u00eenlocuit cu char16_t; am decis s\u0103 renun\u021b\u0103m la utilizarea wchar_t, deoarece char16_t ocup\u0103 2 octe\u021bi pe toate sistemele de operare \u0219i nu compromite compatibilitatea codului \u00eentre Windows \u0219i Linux.<\/p>\n<p>Nu au lipsit mici aventuri. De exemplu, \u00een STLPort iteratorul putea fi convertit implicit la un pointer c\u0103tre element, iar \u00een unele locuri din codul nostru acesta a fost folosit. \u00cen noile biblioteci nu mai era posibil s\u0103 se fac\u0103 asta, iar aceste locuri au trebuit analizate \u0219i rescrise manual. <\/p>\n<p>A\u0219adar, migrarea codului s-a \u00eencheiat, codul se compileaz\u0103 pentru toate sistemele de operare. A venit timpul testelor. <\/p>\n<p>Testele dup\u0103 migrare au ar\u0103tat o sc\u0103dere a performan\u021bei (\u00een unele cazuri cu p\u00e2n\u0103 la 20-30%) \u0219i o cre\u0219tere a consumului de memorie (cu p\u00e2n\u0103 la 10-15%) \u00een compara\u021bie cu vechea versiune a codului. Acest lucru a fost, \u00een parte, legat de func\u021bionarea neoptimizat\u0103 a stringurilor standard. De aceea, a trebuit s\u0103 folosim din nou un string de-al nostru, u\u0219or \u00eembun\u0103t\u0103\u021bit. <\/p>\n<p>De asemenea, a ap\u0103rut o caracteristic\u0103 interesant\u0103 a implement\u0103rii containerelor \u00een bibliotecile \u00eencorporate: std::map \u0219i std::set goale (f\u0103r\u0103 elemente) din bibliotecile \u00eencorporate aloc\u0103 memorie. Iar \u00een unele locuri din codul nostru se creeaz\u0103 un num\u0103r destul de mare de astfel de containere goale, din cauza particularit\u0103\u021bilor implement\u0103rii. Containerele standard aloc\u0103 pu\u021bin\u0103 memorie, pentru un singur element r\u0103d\u0103cin\u0103, dar pentru noi acest lucru s-a dovedit critic \u2013 \u00een unele scenarii am observat o sc\u0103dere semnificativ\u0103 a performan\u021bei \u0219i o cre\u0219tere a consumului de memorie (comparativ cu STLPort). Prin urmare, am \u00eenlocuit \u00een codul nostru aceste dou\u0103 tipuri de containere din bibliotecile \u00eencorporate cu implementarea lor din Boost, unde aceste containere nu aveau aceast\u0103 caracteristic\u0103, ceea ce a rezolvat problema cu \u00eencetinirea \u0219i cre\u0219terea consumului de memorie.<\/p>\n<p>A\u0219a cum se \u00eent\u00e2mpl\u0103 adesea dup\u0103 schimb\u0103ri majore \u00een proiecte mari, prima itera\u021bie a surselor a avut probleme, iar aici ne-a fost de mare ajutor, \u00een special, suportul pentru iteratorii de depanare \u00een implementarea Windows. Pas cu pas am avansat, iar p\u00e2n\u0103 \u00een prim\u0103vara lui 2017 (versiunea 8.3.11 1C:Enterprise) migrarea a fost finalizat\u0103. <\/p>\n<h3>Concluzii<\/h3>\n<p>\nTrecerea la standardul C++14 a durat aproximativ 6 luni. Majoritatea timpului, un singur dezvoltator (dar foarte bine calificat) a lucrat la proiect, iar \u00een etapa final\u0103 s-au al\u0103turat reprezentan\u021bii echipelor responsabile pentru domenii specifice \u2014 UI, cluster de servere, unelte de dezvoltare \u0219i administrare etc.<\/p>\n<p>Trecerea a simplificat semnificativ procesul de migrare c\u0103tre cele mai noi versiuni ale standardului. Astfel, versiunea 1C:Enterprise 8.3.14 (\u00een dezvoltare, lansarea este planificat\u0103 pentru \u00eenceputul anului viitor) a fost deja adaptat\u0103 la standard. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B17\">C++17<\/a><\/noindex>. <\/p>\n<p>Dup\u0103 migrare, dezvoltatorii au avut mai multe oportunit\u0103\u021bi. Dac\u0103 \u00een trecut aveam propria noastr\u0103 variant\u0103 modificat\u0103 de STL \u0219i un singur spa\u021biu de nume std, acum \u00een spa\u021biul de nume std se afl\u0103 clasele standard din bibliotecile \u00eencorporate ale compilatorului, \u00een spa\u021biul de nume stdx \u2013 cele optimizate pentru nevoile noastre, iar \u00een boost \u2013 cea mai recent\u0103 versiune a boost. Dezvoltatorul folose\u0219te acele clase care se potrivesc optim pentru solu\u021bionarea problemelor sale. <\/p>\n<p>De asemenea, implementarea \"nativ\u0103\" a constructorilor de mutare (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/move_constructor\">move constructors<\/a><\/noindex>) pentru mai multe clase ajut\u0103 \u00een dezvoltare. Dac\u0103 o clas\u0103 are un constructor de mutare \u0219i aceast\u0103 clas\u0103 este plasat\u0103 \u00eentr-un container, atunci STL optimizeaz\u0103 copierea elementelor din interiorul containerului (de exemplu, atunci c\u00e2nd containerul se extinde \u0219i este necesar\u0103 modificarea capacit\u0103\u021bii \u0219i realocarea memoriei). <\/p>\n<h3>O lingur\u0103 de cenu\u0219\u0103<\/h3>\n<p>\nCel mai nepl\u0103cut (dar nu critic) rezultat al migra\u021biei \u2014 ne-am confruntat cu o cre\u0219tere a volumului de <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\">fi\u0219iere obj<\/a><\/noindex>, iar rezultatul complet al compil\u0103rii, cu toate fi\u0219ierele intermediare, a ajuns s\u0103 ocupe \u00eentre 60 \u0219i 70 GB. Acest comportament este legat de caracteristicile bibliotecilor standard moderne, care au devenit mai pu\u021bin critice \u00een ceea ce prive\u0219te volumul de fi\u0219iere auxiliare generate. Acest lucru nu afecteaz\u0103 func\u021bionarea aplica\u021biei compilate, dar cauzeaz\u0103 o serie de inconveniente \u00een dezvoltare, \u00een special m\u0103re\u0219te timpul de compilare. De asemenea, cerin\u021bele pentru spa\u021biul liber pe disk pe serverele de compilare \u0219i pe calculatoarele dezvoltatorilor au crescut. Dezvoltatorii no\u0219tri lucreaz\u0103 \u00een paralel la mai multe versiuni ale platformei, iar sute de giga de fi\u0219iere intermediare creeaz\u0103 uneori dificult\u0103\u021bi \u00een munc\u0103. Problema este nepl\u0103cut\u0103, dar nu critic\u0103; solu\u021bionarea ei a fost am\u00e2nat\u0103 pentru moment. Ca o alternativ\u0103 la rezolvarea ei, lu\u0103m \u00een considerare tehnica <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Single_Compilation_Unit\">unity build<\/a><\/noindex> (aceasta, de exemplu, este folosit\u0103 de Google \u00een dezvoltarea browser-ului Chrome).<br \/>\n<br \/>Sursa: <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.3 - 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\/ro\/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.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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\/ro\/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\udd47Cum am tradus 10 milioane de linii de cod C++ pe standardul C++14 (\u0219i apoi pe C++17) | ProHoster","description":"Cu ceva vreme \u00een urm\u0103 (toamna anului 2016), \u00een timpul dezvolt\u0103rii unei noi versiuni a platformei tehnologice 1C:Enterprise, echipa de dezvoltare a ridicat \u00eentrebarea despre suportul pentru noul standard","canonical_url":"https:\/\/prohoster.info\/ro\/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":"ro_RO","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\/ro\/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\/ro\/wp-json\/wp\/v2\/posts\/32466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=32466"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/32466\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/24270"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=32466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=32466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=32466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}