{"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\/it\/blog\/administrirovanie\/kak-my-pereveli-10-millionov-strok-koda-c-na-standart-c-14-a-potom-i-na-c-17","title":{"rendered":"Come abbiamo tradotto 10 milioni di righe di codice C++ allo standard C++14 (e poi a C++17)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Qualche tempo fa (autunno 2016), durante lo sviluppo di una nuova versione della piattaforma tecnologica 1C:Enterprise, nel team di sviluppo si \u00e8 posto il problema del supporto al nuovo standard <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B14\">C++14<\/a><\/noindex> nel nostro codice. Il passaggio al nuovo standard, come supponevamo, ci avrebbe permesso di scrivere molte cose in modo pi\u00f9 elegante, semplice e sicuro, semplificando la manutenzione e il supporto del codice. E in termini di traduzione, sembrerebbe non esserci nulla di straordinario, se non fosse per le dimensioni della base di codice e le specifiche caratteristiche del nostro codice.<\/p>\n<p>Per chi non lo sapesse, 1C:Enterprise \u00e8 un ambiente per lo sviluppo rapido di applicazioni aziendali cross-platform e runtime per la loro esecuzione su diversi sistemi operativi e DBMS. In linea generale, il prodotto comprende:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000885.htm\">Cluster di server applicativi<\/a><\/noindex>, opera su Windows e Linux<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000124.htm\">Cliente<\/a><\/noindex>, in comunicazione con il server tramite http(s) o tramite un proprio protocollo binario, opera su Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/315414\/\">Client web<\/a><\/noindex>, funziona nei browser Chrome, Internet Explorer, Microsoft Edge, Firefox, Safari (scritto in JavaScript)<\/li>\n<li>Ambiente di sviluppo (<noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000008.htm\">Configuratore<\/a><\/noindex>), funziona su Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000813.htm\">Strumenti di amministrazione<\/a><\/noindex> per server applicativi, funzionano su Windows, Linux, macOS<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/wonderland.v8.1c.ru\/blog\/mobilnyy-klient\/\">Client mobile<\/a><\/noindex>, connesso al server tramite http(s), funziona su dispositivi mobili con Android, iOS, Windows<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/283198\/\">Piattaforma mobile<\/a><\/noindex> \u2014 framework per la creazione di applicazioni mobili offline con possibilit\u00e0 di sincronizzazione, funzionano su Android, iOS, Windows<\/li>\n<li>Ambiente di sviluppo <noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/IDE\/\">1C:Enterprise Development Tools<\/a><\/noindex>, scritto in Java<\/li>\n<li>Server <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/1c\/blog\/422903\/\">Sistemi di Interazione<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nCerchiamo di scrivere il codice il pi\u00f9 possibile in modo uniforme per diversi sistemi operativi \u2014 la base di codice del server \u00e8 comune al 99%, quella del client \u00e8 di circa il 95%. La piattaforma tecnologica 1C:Enterprise \u00e8 prevalentemente scritta in C++ e di seguito sono riportate le caratteristiche approssimative del codice:<\/p>\n<ul>\n<li>10 milioni di righe di codice C++,<\/li>\n<li>14 mila file,<\/li>\n<li>60 mila classi,<\/li>\n<li>mezzo milione di metodi.<\/li>\n<\/ul>\n<p>\nE tutto questo doveva essere portato su C++14. Oggi racconteremo come lo abbiamo fatto e quali sfide abbiamo affrontato nel processo.<\/p>\n<p><img decoding=\"async\" alt=\"Come abbiamo tradotto 10 milioni di righe di codice C++ allo standard C++14 (e poi a 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>\nTutto ci\u00f2 che \u00e8 scritto qui sotto riguardo al lavoro lento\/veloce, (non)consumo di memoria delle implementazioni delle classi standard in varie librerie significa una cosa: \u00e8 valido PER NOI. \u00c8 del tutto possibile che le implementazioni standard siano le pi\u00f9 adatte per le vostre esigenze. Noi ci siamo basati sulle nostre necessit\u00e0: abbiamo preso dati tipici dei nostri clienti, li abbiamo elaborati attraverso scenari tipici, abbiamo valutato le prestazioni, l'uso di memoria, ecc., e abbiamo analizzato se questi risultati fossero soddisfacenti o meno per noi e per i nostri clienti. E ci siamo comportati di conseguenza.<\/p>\n<h3>Cosa avevamo<\/h3>\n<p>\nInizialmente scrivevamo il codice della piattaforma 1C:Enterprise 8 su Microsoft Visual Studio. Il progetto \u00e8 stato avviato all'inizio degli anni 2000 e avevamo solo una versione per Windows. Naturalmente, da allora il codice si \u00e8 sviluppato attivamente, molti meccanismi sono stati completamente riscritti. Ma il codice \u00e8 stato scritto secondo lo standard del 1998, e, per esempio, le parentesi angolari destra erano separate da spazi per consentire una compilazione riuscita, in questo modo:<\/p>\n<pre><code class=\"cpp\">vector&lt;vector &gt; IntV;<\/code><\/pre>\n<p>\nNel 2006, con il rilascio della versione della piattaforma 8.1, abbiamo iniziato a supportare Linux e abbiamo adottato una libreria standard di terze parti <noindex><a rel=\"nofollow\" href=\"http:\/\/www.stlport.org\/\">STLPort<\/a><\/noindex>. Una delle ragioni del passaggio era la gestione delle stringhe larghe. Nel nostro codice utilizziamo ovunque std::wstring, basato sul tipo wchar_t. La sua dimensione in Windows \u00e8 di 2 byte, mentre in Linux \u00e8 di 4 byte per impostazione predefinita. Questo ha portato a incompatibilit\u00e0 dei nostri protocolli binari tra client e server, oltre a diversi dati persistenti. Con le opzioni di gcc \u00e8 possibile specificare che la dimensione di wchar_t durante la compilazione sia di 2 byte, ma a quel punto ci si pu\u00f2 scordare dell'uso della libreria standard del compilatore, in quanto utilizza glibc, la quale \u00e8 stata compilata per wchar_t a 4 byte. Ulteriori motivi erano una realizzazione di qualit\u00e0 superiore delle classi standard, supporto per le tabelle hash e persino l'emulazione della semantica del movimento all'interno dei contenitori, che utilizzavamo attivamente. E un'ulteriore ragione, come si suol dire, last but not least, era la performance delle stringhe. Avevamo la nostra classe per le stringhe, poich\u00e9 a causa della specificit\u00e0 del nostro software, le operazioni su stringhe vengono utilizzate molto ampiamente e per noi \u00e8 critico. <\/p>\n<p>La nostra stringa si basa sulle idee di ottimizzazione delle stringhe espresse gi\u00e0 all'inizio degli anni 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\">da Andrei Alexandrescu<\/a><\/noindex>. In seguito, quando Alexandrescu lavorava per Facebook, su sua iniziativa nel motore di Facebook \u00e8 stata utilizzata una stringa che funziona su principi simili (vedi la libreria <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/facebook\/folly\">folly<\/a><\/noindex>).<\/p>\n<p>. Nella nostra stringa sono state utilizzate due tecnologie principali di ottimizzazione:<\/p>\n<ol>\n<li>Per i valori brevi viene utilizzato un buffer interno all'oggetto stringa (che non richiede ulteriori allocazioni di memoria).<\/li>\n<li>Per tutti gli altri viene utilizzata la meccanica <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>. Il valore della stringa \u00e8 memorizzato in un unico posto, durante l'assegnazione\/modifica viene utilizzato un contatore dei riferimenti.<\/li>\n<\/ol>\n<p>\nPer accelerare la compilazione della piattaforma, abbiamo escluso dalla nostra versione di STLPort l'implementazione dello stream (che non utilizzavamo), il che ci ha dato un'accelerazione della compilazione di circa il 20%. Successivamente, ci siamo trovati a dover utilizzare in modo limitato <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Boost\">Boost<\/a><\/noindex>. Boost utilizza attivamente lo stream, in particolare, nelle sue API di servizio (ad esempio, per il logging), quindi ci \u00e8 toccato modificarlo, escludendo l'uso dello stream. Questo, a sua volta, ci ha reso difficile il passaggio a nuove versioni di Boost. <\/p>\n<h3>La terza via<\/h3>\n<p>\nNella transizione allo standard C++14 abbiamo considerato le seguenti opzioni:<\/p>\n<ol>\n<li>Alzare lo STLPort modificato allo standard C++14. L'opzione \u00e8 molto complessa, poich\u00e9 il supporto per STLPort \u00e8 stato interrotto nel 2010 e avremmo dovuto alzare tutto il suo codice da soli.<\/li>\n<li>Passare a un'altra implementazione di STL compatibile con C++14. \u00c8 fondamentale che questa implementazione funzioni sia su Windows che su Linux.<\/li>\n<li>Utilizzare, durante la compilazione, la libreria integrata nel corrispondente compilatore per ogni OS.<\/li>\n<\/ol>\n<p>\nLa prima opzione \u00e8 stata scartata subito a causa del volume troppo grande di lavoro.<\/p>\n<p>Abbiamo riflettuto per un po' sulla seconda opzione; come candidato abbiamo considerato <noindex><a rel=\"nofollow\" href=\"https:\/\/libcxx.llvm.org\/\">libc++<\/a><\/noindex>, ma a quel tempo non funzionava su Windows. Per portare libc++ su Windows, sarebbe stato necessario fare un bel po' di lavoro \u2014 per esempio, scrivere noi stessi tutto ci\u00f2 che riguarda i thread, la sincronizzazione dei thread e l'atomicit\u00e0, poich\u00e9 in libc++ in questi ambiti veniva utilizzato <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/POSIX\">POSIX API<\/a><\/noindex>.<\/p>\n<p>E abbiamo scelto la terza via.<\/p>\n<h3>Transizione<\/h3>\n<p>\nQuindi, dovevamo sostituire l'uso di STLPort con le librerie corrispondenti dei compilatori (Visual Studio 2015 per Windows, gcc 7 per Linux, clang 8 per macOS). <\/p>\n<p>Fortunatamente, il nostro codice \u00e8 stato scritto principalmente seguendo le linee guida e non ha utilizzato trucchi complicati, quindi la migrazione verso le nuove librerie \u00e8 avvenuta in modo relativamente fluido, grazie a script che sostituivano nei file sorgente i nomi di tipi, classi, namespace e inclusioni. La migrazione ha riguardato 10.000 file sorgente (su 14.000). wchar_t \u00e8 stato sostituito con char16_t; abbiamo deciso di rinunciare all'uso di wchar_t, poich\u00e9 char16_t occupa 2 byte su tutti i sistemi operativi e non compromette la compatibilit\u00e0 del codice tra Windows e Linux.<\/p>\n<p>Non sono mancati piccoli imprevisti. Ad esempio, in STLPort gli iteratori potevano essere implicitamente convertiti in puntatori agli elementi, e in alcune parti del nostro codice ci\u00f2 \u00e8 stato utilizzato. Nelle nuove librerie questo non era pi\u00f9 possibile, e questi punti hanno dovuto essere analizzati e riscritti manualmente. <\/p>\n<p>Quindi, la migrazione del codice \u00e8 completata, il codice \u00e8 compilato per tutti i sistemi operativi. \u00c8 tempo di test. <\/p>\n<p>I test dopo la transizione hanno mostrato un calo delle prestazioni (fino al 20-30% in alcuni casi) e un aumento dell'uso della memoria (fino al 10-15%) rispetto alla vecchia versione del codice. Questo era, in particolare, dovuto al funzionamento non ottimale delle stringhe standard. Pertanto, abbiamo dovuto utilizzare nuovamente la nostra stringa, leggermente modificata. <\/p>\n<p>\u00c8 emersa anche un'interessante caratteristica dell'implementazione dei contenitori nelle librerie incorporate: std::map e std::set vuoti (senza elementi) delle librerie incorporate allocano memoria. E noi, a causa delle particolarit\u00e0 della nostra implementazione, creiamo in alcune parti del codice un numero considerevole di contenitori vuoti di questo tipo. I contenitori standard allocano una quantit\u00e0 minima di memoria, per un singolo elemento radice, ma per noi questo si \u00e8 rivelato critico: in alcuni scenari la nostra prestazione \u00e8 notevolmente diminuita e il consumo di memoria \u00e8 aumentato (rispetto a STLPort). Pertanto, abbiamo sostituito nel nostro codice questi due tipi di contenitori delle librerie incorporate con la loro implementazione di Boost, dove tali contenitori non avevano questa caratteristica, e questo ha risolto il problema legato al rallentamento e all'aumento del consumo di memoria.<\/p>\n<p>Come spesso accade dopo cambiamenti su larga scala in grandi progetti, la prima iterazione dei sorgenti non ha funzionato senza problemi, e in questo ci \u00e8 stata molto utile, in particolare, la supporto degli iteratori di debug nell'implementazione per Windows. Passo dopo passo, ci siamo mossi avanti, e nella primavera del 2017 (versione 8.3.11 di 1C:Enterprise) la migrazione \u00e8 stata completata. <\/p>\n<h3>Conclusioni<\/h3>\n<p>\nIl passaggio allo standard C++14 ha richiesto circa 6 mesi. La maggior parte del tempo, un solo sviluppatore (molto qualificato) ha lavorato sul progetto, e nella fase finale sono stati coinvolti rappresentanti dei team responsabili di aree specifiche \u2014 UI, cluster di server, strumenti di sviluppo e amministrazione, ecc.<\/p>\n<p>Il passaggio ha notevolmente semplificato il nostro lavoro di migrazione alle versioni pi\u00f9 recenti dello standard. Ad esempio, la versione 1C:Enterprise 8.3.14 (in fase di sviluppo, il rilascio \u00e8 previsto per l'inizio del prossimo anno) \u00e8 gi\u00e0 stata convertita allo standard <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/C%2B%2B17\">C++17<\/a><\/noindex>. <\/p>\n<p>Dopo la migrazione, gli sviluppatori hanno avuto a disposizione maggiori opportunit\u00e0. Se prima avevamo una nostra versione modificata dello STL e uno spazio dei nomi std, ora nello spazio dei nomi std ci sono classi standard dalle librerie integrate del compilatore, nello spazio dei nomi stdx si trovano le nostre stringhe e contenitori ottimizzati per i nostri compiti, e in boost \u2013 una versione aggiornata di boost. Gli sviluppatori possono utilizzare le classi che meglio si adattano alla risoluzione dei loro compiti. <\/p>\n<p>Aiuta nello sviluppo anche la \"nativa\" implementazione dei costruttori di spostamento (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/move_constructor\">move constructors<\/a><\/noindex>) per diverse classi. Se una classe ha un costruttore di spostamento e questa classe viene inserita in un contenitore, allora STL ottimizza la copia degli elementi all'interno del contenitore (ad esempio, quando il contenitore si espande e deve cambiare capacity e riallocare la memoria). <\/p>\n<h3>Un aspetto negativo<\/h3>\n<p>\nUno degli effetti pi\u00f9 fastidiosi (ma non critici) della migrazione \u00e8 stato l'aumento del 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\">dei file obj<\/a><\/noindex>, e il risultato completo della build con tutti i file intermedi \u00e8 diventato di circa 60\u201370 GB. Questo comportamento \u00e8 legato alle caratteristiche delle moderne librerie standard, che tendono a non essere pi\u00f9 cos\u00ec critiche riguardo alla quantit\u00e0 di file di servizio generati. Ci\u00f2 non influisce sul funzionamento dell'applicazione compilata, ma crea alcuni disagi nello sviluppo, in particolare aumenta il tempo di compilazione. Aumentano anche i requisiti di spazio libero su disco nei server di build e sui computer degli sviluppatori. I nostri sviluppatori lavorano contemporaneamente su pi\u00f9 versioni della piattaforma, e centinaia di gigabyte di file intermedi creano a volte difficolt\u00e0 nel lavoro. Il problema \u00e8 sgradevole, ma non critico; abbiamo per ora rimandato la sua risoluzione. Come una delle opzioni per risolverlo, stiamo considerando la tecnica <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Single_Compilation_Unit\">unity build<\/a><\/noindex> (in particolare, lo utilizza Google nello sviluppo del browser Chrome).<br \/>\n<br \/>Fonte: <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\/it\/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=\"it_IT\" \/>\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\/it\/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\udd47Come abbiamo tradotto 10 milioni di righe di codice C++ nello standard C++14 (e poi in C++17) | ProHoster","description":"Qualche tempo fa (autunno 2016), durante lo sviluppo di una nuova versione della piattaforma tecnologica 1C:Enterprise, nel team di sviluppo si \u00e8 posto il problema del supporto al nuovo standard","canonical_url":"https:\/\/prohoster.info\/it\/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":"it_IT","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\/it\/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\/it\/wp-json\/wp\/v2\/posts\/32466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=32466"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/32466\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/24270"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=32466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=32466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=32466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}