Perché C++ batte ancora Rust nell'era dell'intelligenza artificiale

Perché C++ batte ancora Rust nell'era dell'intelligenza artificiale

Perché C++ batte ancora Rust nell'era dell'intelligenza artificiale

Introduzione

Le discussioni sui linguaggi di programmazione spesso diventano teatro morale molto prima di diventare ingegneria. Una lingua viene descritta come pulita, l’altra come gravata. Uno è immaginato come il futuro, l'altro come il bagaglio del passato. Queste storie sono emotivamente soddisfacenti perché fanno sembrare la storia ordinata. Inoltre, fuorviano i team che devono spedire i sistemi rispettando scadenze, budget, vincoli di integrazione e ora una forza aggiuntiva che non esisteva allo stesso modo dieci anni fa: assistenti e agenti di codifica AI.

Una volta che la generazione del codice diventa parte della consegna quotidiana, la domanda cambia. Non è più solo "Quale linguaggio è elegante?" o "Quale lingua è sicura per impostazione predefinita?" La domanda più difficile e pratica diventa questa: se un team si aspetta che i sistemi di intelligenza artificiale aiutino a scrivere, effettuare il refactoring, il benchmarking, l’integrazione e il debug del codice di produzione, quale linguaggio offre attualmente a tali sistemi l’ambiente più ricco in cui essere utili? La mia risposta rimane C++, e il cuore della discussione non è né la nostalgia né il machismo. È densità.

Il C++ si trova ancora all'interno di un mondo più denso di codice pubblico, infrastruttura distribuita, strumenti dei fornitori, esempi di piattaforme, folklore di ottimizzazione e cicatrici di produzione reali rispetto a Rust. I modelli di intelligenza artificiale imparano da quella densità. Non imparano solo la sintassi. Imparano come le persone hanno messo insieme sistemi di grandi dimensioni, come si sono evoluti i file di build, come sono state fatte funzionare le integrazioni antiestetiche, come sono stati diagnosticati i bug di basso livello e come il codice sensibile alle prestazioni è stato effettivamente scritto con rabbia piuttosto che in teoria. Quando in seguito a questi modelli viene chiesto di aiutare con l’ingegneria reale, la forma di quella memoria storica conta.

Ciò non significa che Rust sia debole, poco serio o irrilevante. Al contrario, Rust ha esercitato una sana pressione sulla programmazione dei sistemi. Ha reso impossibile ignorare la sicurezza della memoria, ha migliorato il tono di molte conversazioni di ingegneria e ha prodotto strumenti e librerie davvero potenti. Ma l’esistenza dei punti di forza di Rust non cancella automaticamente gli attuali vantaggi del C++ nella distribuzione assistita dall’intelligenza artificiale. L’ingegneria matura spesso richiede di possedere entrambe le verità contemporaneamente.

Prima le prove, poi gli slogan

Un'argomentazione attenta inizia separando ciò che può essere osservato pubblicamente da ciò che deve essere dedotto. I set di dati pubblici utilizzati nella ricerca sui modelli di codice, come The Stack, mostrano sostanzialmente più C++ che Rust. I sondaggi tra gli sviluppatori pubblici e le tendenze del linguaggio GitHub continuano a mostrare un utilizzo assoluto e più ampio del C++ nel settore. L'infrastruttura pubblica di intelligenza artificiale, dagli SDK dei fornitori ai runtime di inferenza ottimizzati fino alle librerie matematiche di basso livello, espone ancora un mondo che è profondamente modellato su C e C++. Gli sforzi di benchmarking pubblico come CRUST-Bench suggeriscono anche che i modelli attuali hanno ancora difficoltà a generare costantemente Rust sicuro e idiomatico, nel senso forte che le comunità Rust apprezzano.

Da questi fatti traiamo una deduzione, non un dogma. La deduzione è che i sistemi di intelligenza artificiale hanno attualmente maggiori probabilità di generare C++ utile alla produzione, integrabile e ottimizzabile in molti domini di sistema perché l’ambiente circostante per C++ è più ricco. Questa non è magia. È esposizione combinata con feedback. Un linguaggio con più repository, più script di build, più esempi relativi all'hardware, più integrazioni di fornitori, più correzioni di bug pubbliche, più indagini sulle prestazioni e più storie di guerre di produzione offre a un modello più modi per essere approssimativamente giusto prima ancora che un ingegnere umano inizi a correggerlo.

Questo punto viene spesso contrastato perché sembra ingeneroso per la nuova lingua. Ma non è un insulto nei confronti di Rust affermare che ha avuto meno tempo per accumulare sedimenti di ingegneria pubblica. Il C++ è integrato da decenni in sistemi operativi, browser, database, stack multimediali, strumenti di sicurezza, motori di gioco, telecomunicazioni, calcolo scientifico, prodotti integrati e sistemi finanziari. La ruggine è cresciuta rapidamente e in modo ammirevole, ma la crescita non è la stessa cosa della profondità geologica. I modelli di intelligenza artificiale assorbono la profondità.

Perché le dimensioni del corpo contano più di quanto si ammetta

Gli ingegneri a volte trattano il volume dei dati di addestramento come se fosse un argomento di discussione grezzo. In pratica conta in un modo molto più umano. Un agente AI che lavora in una base di codice di produzione di solito non inventa un algoritmo perfetto partendo dai principi primi. Sta facendo qualcosa di più complicato. Potrebbe essere l'aggiornamento di un file CMake, l'adattamento a un reclamo del compilatore su una piattaforma, la sostituzione di un contenitore hot-path, il confezionamento di un'API del fornitore, la conversione di layout di immagini o tensori, la correzione di una mancata corrispondenza ABI o la creazione di un vecchio sottosistema nativo leggermente meno doloroso senza danneggiare tutto ciò che lo circonda.

Questi compiti premiano la familiarità con il codice ordinario, imperfetto e vissuto. L'agente trae vantaggio dall'aver visto non solo esempi chiari da libri di testo, ma migliaia di tentativi reali di risolvere problemi adiacenti. Il C++ fornisce ai modelli molto più di quel materiale. C'è un C++ più moderno, un C++ legacy che viene lentamente riparato, un C++ più basato sui benchmark, un C++ più imbarazzante che in qualche modo gestisce ancora attività importanti e più esempi di persone che affrontano esattamente il tipo di compromessi richiesti dai sistemi reali.

Questo è il motivo per cui la "produzione disordinata C++" costituisce ancora un prezioso dato di addestramento. Alcuni ingegneri sentono questa frase e immaginano che indebolisca il caso. In realtà lo rafforza. I sistemi di produzione non sono composti interamente da eleganti moduli greenfield. Includono interfacce legacy, strani presupposti ABI, condizionali della piattaforma, peculiarità dell'hardware, migrazioni parziali e codice sopravvissuto perché era utile prima che fosse bello. Se un sistema di intelligenza artificiale ha visto molti più esempi di questo panorama in C++, è semplicemente più preparato ad aiutare all’interno di tale panorama.

Vale la pena citare apertamente un controesempio. Se un team sta costruendo un piccolo servizio greenfield con una forte esperienza in Rust, chiari requisiti di sicurezza, modeste esigenze di integrazione e nessun pesante ecosistema nativo attorno ad esso, Rust potrebbe essere una scelta locale migliore. In quella situazione l’argomento relativo alla dimensione del corpus è meno decisivo perché il contesto ingegneristico circostante è più semplice e il team umano può mantenere il sistema all’interno di una fascia di complessità più ristretta. Il punto non è che il C++ prevalga su ogni argomento. Il punto è che man mano che il problema diventa più vecchio, più strano, più sensibile alle prestazioni e più legato all’infrastruttura nativa esistente, C++ diventa sempre più il linguaggio più semplice per i sistemi di intelligenza artificiale con cui aiutare in modo efficace.

Il mondo delle infrastrutture AI è ancora modellato su C++

Anche se ignorassimo completamente il volume dei dati di addestramento, ci sarebbe comunque una seconda forza che spingerebbe il default verso C++: l’infrastruttura alla base dei moderni prodotti di intelligenza artificiale rimane fortemente nativa. CUDA, librerie matematiche ottimizzate, componenti interni di runtime ONNX, oneDNN, OpenVINO, implementazioni di tokenizer, pipeline di preelaborazione multimediale, acceleratori di model-serving, SDK di fornitori di hardware e molti runtime di distribuzione sono scritti in C o C++ o espongono lì le loro interfacce più serie. Ciò non significa che Rust non possa richiamarli. Ciò significa che il percorso più breve attraverso il paesaggio è ancora solitamente un percorso C o C++.

Ciò è importante perché gli agenti di codifica dell’intelligenza artificiale non sono utili nel vuoto. Sono utili all'interno dei grafici delle dipendenze. Un modello a cui viene chiesto di aiutare a integrare un runtime, eseguire il debug di una build, ottimizzare un percorso attivo o ragionare sulla proprietà oltre il confine dell'SDK di un fornitore è avvantaggiato quando ha visto molti esempi adiacenti nella stessa famiglia linguistica. C++ beneficia ancora di questa familiarità ambientale più di Rust nella maggior parte dei lavori infrastrutturali IA critici per le prestazioni.

È qui che diventa importante anche la conversazione sui cicli di feedback. Il codice generato dall’intelligenza artificiale diventa veramente prezioso solo quando gli esseri umani possono verificarlo rapidamente. C++ spesso offre ai team una verifica locale più completa in questi domini perché l'ecosistema attorno al benchmarking, alla profilazione, al replay, ai disinfettanti, ai contatori hardware e alla diagnostica di basso livello è così maturo. Quando un agente propone una modifica in un percorso di inferenza C++, un team può spesso compilarlo, profilarlo, ispezionare il comportamento di allocazione, confrontare le distribuzioni di latenza ed eseguire rapidamente l'iterazione. Anche Rust dispone di strumenti potenti, ma in molti sistemi nativi adiacenti all'intelligenza artificiale la densità combinata di librerie, esempi, profiler e pratica esistente rende ancora il C++ il luogo più semplice per eseguire stretti cicli di correzione human-in-the-loop.

Perché i team spesso si muovono più velocemente con C++ anche quando Rust sembra più pulito

Questo è il punto che tende a offendere l'ideologia, perché suona scortese nei confronti della pulizia. La ruggine spesso appare più pulita sulla lavagna. La proprietà è esplicita. Il compilatore custodisce errori importanti. La cultura della correttezza è ammirevole. Ma la velocità di produzione non è identica all’eleganza del linguaggio. La reale velocità di consegna emerge dall'intero ciclo: base di codice esistente, librerie disponibili, pool di talenti, strumenti di debug, vincoli di distribuzione, qualità dell'assistenza AI e costo per apportare un'altra modifica il mese prossimo.

Il C++ attualmente vince questo ciclo più ampio in molti sistemi dell’era dell’intelligenza artificiale perché i team possono chiedere di più al mondo circostante senza abbandonare il linguaggio. Possono integrare vecchie librerie native, collegare profiler creati pensando al lavoro sulle prestazioni native, ottimizzare gli allocatori, sfruttare funzionalità specifiche della piattaforma e attingere da un corpo molto più ampio di esempi pubblici quando qualcosa va storto. Gli assistenti AI beneficiano esattamente della stessa realtà. Quando il mondo attorno al modello è denso e molto frequentato, le bozze del modello migliorano più rapidamente.

Immagina due team che creano un servizio di inferenza sensibile alla latenza con una preelaborazione personalizzata, una matrice di distribuzione complicata e la necessità di ripetute ottimizzazioni delle prestazioni. Il team di Rust potrebbe produrre un insieme più piccolo di bug di sicurezza della memoria, e questo non è banale. Ma se il team C++ riesce a integrare l’ecosistema in modo più diretto, a ottenere suggerimenti di intelligenza artificiale più forti nella base di codice effettiva di cui dispone e a verificare i cambiamenti delle prestazioni più rapidamente con strumenti nativi maturi, il risultato complessivo della distribuzione potrebbe comunque favorire il C++. In termini commerciali, ciò conta più del fatto che una lingua abbia vinto una discussione filosofica online.

Un utile controesempio ci mantiene onesti. Se il rischio dominante in un progetto non è l’integrazione o l’evoluzione delle prestazioni ma la sicurezza della memoria in un nuovo servizio con dipendenze relativamente semplici, Rust può assolutamente creare risultati organizzativi migliori. L’errore è prendere quella verità ed esportarla indiscriminatamente in ogni problema dei sistemi adiacenti all’intelligenza artificiale. Le lingue vincono nei contesti, non nei sermoni.

Ciò che la ruggine ha ancora ragione

Rust merita rispetto e l'argomentazione a favore del C++ è più debole quando fa una caricatura di Rust. La ruggine è eccellente nel rendere visibili le ipotesi non sicure. Crea una forte disciplina riguardo alla proprietà e alla durata. Spesso è una scelta convincente per le infrastrutture greenfield in cui la correttezza e la manutenibilità prevalgono sulla compatibilità con un mondo nativo esistente. In alcuni team, Rust migliora anche la chiarezza delle assunzioni perché la base di codice stessa impone un certo tipo di serietà ingegneristica.

È anche importante dire chiaramente che il C++ non vince per impostazione predefinita solo perché è più vecchio. Il C++ indisciplinato rimane pericoloso. Se un team ha una cultura di revisione debole, nessuna abitudine alla profilazione, test inadeguati e nessun rispetto per l’osservabilità, allora corpora più grandi e strumenti più ricchi non lo salveranno. I sistemi di intelligenza artificiale possono amplificare quel caos con la stessa facilità con cui possono accelerare la buona ingegneria. La vera affermazione è più ristretta e più pratica: dati i team disciplinati che risolvono problemi di sistemi legati alle prestazioni e all’integrazione, dell’era dell’intelligenza artificiale, C++ è ancora oggi la scommessa predefinita più forte perché gli agenti, gli strumenti e la gravità dell’ecosistema lo rafforzano.

Questo è il motivo per cui preferisco la frase scommessa predefinita piuttosto che vincitore universale. Una scommessa predefinita è ciò che scegli quando l'onere della prova non è ancora stato spostato altrove. Rust può guadagnare questo cambiamento in progetti specifici. Ma il C++ inizia ancora con più prove a suo favore ogni volta che il lavoro è profondamente intrecciato con l’infrastruttura IA nativa, prestazioni di basso livello, sistemi di produzione di lunga durata o il tipo di codebase che gli agenti IA hanno visto in grande quantità al pubblico.

Un modo pratico per decidere

Se il percorso caldo è nativo, il grafico delle dipendenze è nativo, la storia della profilazione è importante e ti aspetti che gli assistenti AI ti aiutino all'interno del disordinato codice di produzione reale, C++ merita di essere la tua prima discussione seria sul linguaggio. Se il sistema è greenfield, prevale la questione della sicurezza, l’ecosistema circostante è già a forma di Rust e il problema non dipende fortemente dai vecchi strati nativi, Rust diventa più attraente. Se il sistema contiene entrambi i mondi, cosa che molti fanno, la risposta matura è spesso l’architettura ibrida piuttosto che la purezza tribale.

Questo quadro calma la conversazione perché restituisce la decisione di lavorare piuttosto che l’identità. Un runtime di inferenza nativo all'interno di una piattaforma C++ esistente non rappresenta lo stesso problema di un nuovo servizio del piano di controllo. Una pipeline multimediale a bassa latenza non rappresenta lo stesso problema di un'API back-end. Un componente edge che serve il modello non è lo stesso problema di un motore di transizione di stato nativo della catena. Una volta dato un nome all’opera vera e propria, la scelta del linguaggio di solito appare meno ideologica e più ovvia.

C’è anche un vantaggio umano nel prendere una decisione in questo modo. I team diventano più cooperativi quando smettono di chiedersi quale lingua meriti ammirazione e iniziano a chiedersi quale lingua offra al sistema attuale le migliori possibilità di diventare affidabile, intelligibile e migliorabile. L’assistenza dell’intelligenza artificiale rende questo aspetto ancora più importante. Gli agenti sono potenti quando sono inseriti in una cultura di verifica, non quando vengono utilizzati per decorare il fandom linguistico con sicurezza sintetica.

La vera opportunità

L’opportunità più profonda nell’era dell’intelligenza artificiale non è semplicemente che gli agenti possano scrivere codice. Il fatto è che ora possono partecipare all’intero ciclo di feedback attorno ai sistemi maturi: leggere il vecchio codice, proporre modifiche, migliorare i benchmark, far emergere indizi di profiler, tradurre idee grezze in esperimenti compilabili e aiutare gli ingegneri a passare dal sospetto alla misurazione più velocemente di prima. In quel mondo, la lingua che trae maggiori benefici non è necessariamente quella con la storia teorica più bella. È quello con la più fitta rete di realtà pubblica, pratica e comprovata.

Oggi, per un'ampia classe di problemi sistemici seri, quel linguaggio è ancora C++. E questa è una buona notizia, non perché l’industria dovrebbe smettere di imparare da Rust, ma perché i team possono utilizzare l’enorme corpus di conoscenze native esistenti invece di fingere che siano svanite nel momento in cui è arrivata l’intelligenza artificiale. L’atteggiamento più produttivo non è il trionfalismo. È gratitudine. Il C++ ha accumulato decenni di memoria ingegneristica reale e i sistemi di intelligenza artificiale ora rendono quella memoria più facile da usare. Le squadre sagge ne trarranno vantaggio.

Laboratorio pratico: crea e migliora una pipeline di punteggio nativa

Se un articolo sulla scelta della lingua nell’era dell’intelligenza artificiale non contiene codice, rischia di diventare un sermone.

Costruiamo quindi una piccola utility C++ nativa del tipo che agli agenti di intelligenza artificiale viene costantemente chiesto di migliorare nelle aziende reali: una pipeline di punteggio testuale che carica dati, calcola funzionalità semplici, ordina i risultati e stampa le righe superiori.

È modesto apposta. La maggior parte dell’ingegneria di produzione è modesta.

__CODICE_0__

#include <algorithm>
#include <chrono>
#include <cctype>
#include <fstream>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>

struct Sample {
    std::string text;
    double score = 0.0;
};

static int count_digits(std::string_view s) {
    int n = 0;
    for (unsigned char c : s) {
        n += std::isdigit(c) ? 1 : 0;
    }
    return n;
}

static int count_upper(std::string_view s) {
    int n = 0;
    for (unsigned char c : s) {
        n += std::isupper(c) ? 1 : 0;
    }
    return n;
}

static int count_punct(std::string_view s) {
    int n = 0;
    for (unsigned char c : s) {
        n += std::ispunct(c) ? 1 : 0;
    }
    return n;
}

static double score_line(std::string_view s) {
    const auto len = static_cast<double>(s.size());
    const auto digits = static_cast<double>(count_digits(s));
    const auto upper = static_cast<double>(count_upper(s));
    const auto punct = static_cast<double>(count_punct(s));
    return len * 0.03 + digits * 0.7 + upper * 0.15 - punct * 0.05;
}

int main(int argc, char** argv) {
    if (argc < 2) {
        std::cerr << "usage: scorer <input-file>\n";
        return 1;
    }

    std::ifstream in(argv[1]);
    if (!in) {
        std::cerr << "cannot open input file\n";
        return 1;
    }

    std::vector<Sample> rows;
    rows.reserve(200000);

    std::string line;
    while (std::getline(in, line)) {
        rows.push_back({line, 0.0});
    }

    const auto t0 = std::chrono::steady_clock::now();
    for (auto& row : rows) {
        row.score = score_line(row.text);
    }
    std::sort(rows.begin(), rows.end(), [](const Sample& a, const Sample& b) {
        return a.score > b.score;
    });
    const auto t1 = std::chrono::steady_clock::now();

    const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count();
    std::cout << "processed " << rows.size() << " rows in " << ms << " ms\n";

    const size_t limit = std::min<size_t>(5, rows.size());
    for (size_t i = 0; i < limit; ++i) {
        std::cout << rows[i].score << " | " << rows[i].text << "\n";
    }
}

Costruire

Su Linux o macOS:

g++ -O2 -std=c++20 -o scorer main.cpp
./scorer sample.txt

Su Windows con MSVC:

cl /O2 /std:c++20 main.cpp
.\main.exe sample.txt

Perché questo piccolo programma è utile

Perché è esattamente il tipo di codice in cui l'ingegneria assistita dall'intelligenza artificiale diventa tangibile:

  • è nativo
  • tocca corde e memoria
  • ha un tempo di esecuzione misurabile
  • può essere profilato
  • può essere migliorato in modo incrementale

Questo è il vero habitat di molti agenti C++ oggi: non grandi dimostrazioni, ma normali programmi nativi che devono migliorare senza essere reinventati.

Attività di prova per appassionati

Se vuoi trasformare l'articolo in un esercizio pratico, prova questi:

  1. Chiedi al tuo agente di codifica preferito di ottimizzare il programma senza modificare l'output. Controlla se riduce i passaggi duplicati o i provvisori non necessari.
  2. Aggiungi tempistiche separate per il caricamento, il punteggio e l'ordinamento dei file. Verifica dove va realmente il tempo.
  3. Sostituisci l'input con un milione di righe e confronta la qualità delle ottimizzazioni suggerite da diversi agenti.
  4. Porta l'utilità su Rust e confronta onestamente l'esperienza: cosa sembrava più chiaro, cosa sembrava più pesante e quali strumenti circostanti sembravano più maturi per questo compito esatto.
  5. Esegui la versione C++ sotto un profiler e scrivi se la tua prima ipotesi sull'hotspot era effettivamente corretta.

Questo è un piccolo esercizio, ma proprio per questo è utile. La maggior parte dei dibattiti ingegneristici diventano più veritieri quando sono costretti a sopravvivere al contatto con un piccolo programma reale.

Riepilogo

La ruggine merita il rispetto che riceve. Ha innalzato lo standard per le conversazioni di sicurezza e ha fornito alla programmazione dei sistemi un insieme più sano di impostazioni predefinite. Ma l’era dell’intelligenza artificiale non premia solo i default. È premiante il linguaggio che si trova al centro del più grande corpus vivente di codice reale, dell’ecosistema più profondo di integrazioni di basso livello, della cultura di ottimizzazione più ricca e del ciclo pratico più veloce dalla bozza generata al risultato di produzione misurabile. Oggi questo descrive ancora il C++ più fortemente di Rust.

Ciò non rende il C++ moralmente superiore e non rende Rust irrilevante. Significa semplicemente che, per molti gravi problemi dei sistemi nativi, gli agenti IA hanno ancora più terreno utile sotto i loro piedi quando il mondo di destinazione è C++. I team che capiscono questo possono prendere decisioni migliori senza drammi. Possono imparare da Rust, dove Rust è più forte, e continuare a utilizzare l'immensa memoria accumulata del C++ dove quella memoria ha il maggior valore economico.

Riferimenti

  1. GitHub Octoverse 2024: https://github.blog/news-insights/octoverse/octoverse-2024/
  2. GitHub Octoverse 2025: https://github.blog/news-insights/octoverse/octoverse-a-new-developer-joins-github-every-second-as-ai-leads-typescript-to-1/
  3. Sondaggio per sviluppatori Stack Overflow 2023: https://survey.stackoverflow.co/2023
  4. Sondaggio per sviluppatori Stack Overflow 2025 Sezione tecnologia: https://survey.stackoverflow.co/2025/technology/
  5. La scheda del set di dati Stack: https://huggingface.co/datasets/bigcode/the-stack
  6. La pila di fogli: https://arxiv.org/abs/2211.15533
  7. Documento ICLR 2025 sull'impatto dei dati del codice nella pre-formazione: https://openreview.net/pdf?id=zSfeN1uAcx
  8. CRUST-Bench: un benchmark completo per la transizione da C-a-safe-Rust: https://arxiv.org/abs/2504.15254
  9. Guida alla programmazione CUDA C++: https://docs.nvidia.com/cuda/cuda-c-programming-guide/
  10. API C/C++ di runtime ONNX: https://onnxruntime.ai/docs/api/c/index.html
  11. Documentazione del frontend PyTorch C++: https://docs.pytorch.org/cppdocs/frontend.html
  12. Linee guida di base per C++: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
Philip P.

Philip P. – CTO

Back to Blogs

Contatto

Inizia la conversazione

Bastano poche righe chiare. Descrivi il sistema, la pressione e la decisione che è bloccata. Oppure scrivi direttamente a midgard@stofu.io.

01 What the system does
02 What hurts now
03 What decision is blocked
04 Optional: logs, specs, traces, diffs
0 / 10000