Cosa può fare il C ++ troppo duro o disordinato in qualsiasi altra lingua?

StackOverflow https://stackoverflow.com/questions/423335

  •  05-07-2019
  •  | 
  •  

Domanda

Sento ancora che C ++ offre alcune cose che non possono essere battute. Non è mia intenzione iniziare una guerra di fiamme qui, per favore, se hai opinioni forti sul non amare il C ++ non sfogarti qui. Sono interessato a ricevere notizie dai guru del C ++ sul perché restino fedeli.

Sono particolarmente interessato agli aspetti del C ++ che sono poco conosciuti o sottoutilizzati.

Modifica: Persone, ti preghiamo di leggere almeno in modo sommario altre risposte per assicurarti di non duplicare ciò che è già stato detto, se sei d'accordo con quello che ha detto qualcun altro, votalo!

È stato utile?

Soluzione

Sono rimasto con C ++ in quanto è ancora il linguaggio per scopi generici con le prestazioni più elevate per le applicazioni che devono combinare l'efficienza e complessità. Ad esempio, scrivo software di modellazione di superficie in tempo reale per dispositivi portatili per l'industria topografica. Date le risorse limitate, Java, C #, ecc ... non forniscono le caratteristiche prestazionali necessarie, mentre linguaggi di livello inferiore come C sono molto più lenti a svilupparsi in considerazione delle caratteristiche di astrazione più deboli. La gamma di livelli di astrazione disponibili per uno sviluppatore C ++ è enorme, ad un estremo posso sovraccaricare gli operatori aritmetici in modo tale da poter dire qualcosa come MaterialVolume = DesignSurface - GroundSurface mentre allo stesso tempo eseguo un numero di diversi heap per gestire la memoria in modo più efficiente per la mia app su un dispositivo specifico. Combina questo con una vasta gamma di fonti disponibili gratuitamente per risolvere praticamente qualsiasi problema comune e hai un diavolo di un linguaggio di sviluppo potente.

Il C ++ è ancora la soluzione di sviluppo ottimale per la maggior parte dei problemi nella maggior parte dei domini? Probabilmente no, anche se a un pizzico può ancora essere usato per la maggior parte di essi. È ancora la soluzione migliore per lo sviluppo efficiente di applicazioni ad alte prestazioni? IMHO senza dubbio.

Altri suggerimenti

RAII / finalizzazione deterministica . No, la garbage collection non è altrettanto valida quando hai a che fare con una risorsa scarsa e condivisa.

Accesso illimitato alle API del sistema operativo .

Spararsi al piede.

Nessun altro linguaggio offre una tale gamma creativa di strumenti. Puntatori, ereditarietà multipla, modelli, sovraccarico dell'operatore e un preprocessore.

Un linguaggio meravigliosamente potente che offre anche abbondanti opportunità per sparare ai piedi.

Modifica: mi scuso se il mio tentativo zoppo di umorismo ha offeso alcuni. Considero C ++ il linguaggio più potente che io abbia mai usato, con capacità di codificare a livello di linguaggio assembly quando desiderato e ad un alto livello di astrazione quando desiderato. Il C ++ è stato il mio linguaggio principale sin dai primi anni '90.

La mia risposta si basava su anni di esperienza nel spararmi al piede. Almeno C ++ mi permette di farlo in modo elegante.

La distruzione deterministica degli oggetti porta ad alcuni magnifici modelli di design. Ad esempio, sebbene RAII non sia una tecnica così generale come la garbage collection, porta ad alcune straordinarie capacità che non è possibile ottenere con GC.

C ++ è anche unico in quanto ha un preprocessore completo di Turing. Ciò consente di preferire (come al contrario di differire) molte attività di codice per compilare il tempo anziché il tempo di esecuzione. Ad esempio, nel codice reale potresti avere un'istruzione assert () per verificare che non accada mai. La realtà è che prima o poi succederà ... e succederà alle 3:00 del mattino quando sei in vacanza. L'asserzione del preprocessore C ++ esegue lo stesso test in fase di compilazione. Le asserzioni in fase di compilazione falliscono tra le 8:00 e le 17:00 mentre si è seduti davanti al computer a guardare la compilazione del codice; le asserzioni di runtime falliscono alle 3:00 del mattino quando dormi alle Hawaii. È abbastanza facile vedere la vittoria lì.

Nella maggior parte delle lingue, i modelli di strategia vengono eseguiti in fase di esecuzione e generano eccezioni in caso di mancata corrispondenza del tipo. In C ++, le strategie possono essere eseguite in fase di compilazione tramite la struttura del preprocessore e possono essere garantite la tipesafe.

Scrivi assembly inline (MMX, SSE, ecc.).

Distruzione di oggetti deterministici. Cioè veri distruttori. Semplifica la gestione delle risorse scarse. Consente RAII.

Accesso più semplice ai dati binari strutturati. È più semplice eseguire il cast di una regione di memoria come struct piuttosto che analizzarla e copiare ogni valore in una struct.

Eredità multipla. Non tutto può essere fatto con le interfacce. A volte vuoi anche ereditare la funzionalità effettiva.

Penso che loderò C ++ per la sua capacità di usare modelli per catturare espressioni ed eseguirlo pigramente quando è necessario. Per coloro che non sanno di cosa si tratta, qui è un esempio.

I mixin di template forniscono un riutilizzo che non ho visto altrove. Con loro puoi costruire un grande oggetto con un sacco di comportamento come se avessi scritto tutto a mano. Ma tutti questi piccoli aspetti della sua funzionalità possono essere riutilizzati, è particolarmente grande per l'implementazione di parti di un'interfaccia (o del tutto), in cui stai implementando una serie di interfacce. L'oggetto risultante è fulmineo perché è tutto in linea.

La velocità potrebbe non essere importante in molti casi, ma quando si scrive software componente e gli utenti possono combinare componenti in modi complicati e impensati per fare le cose, la velocità di inline e C ++ sembra consentire alle strutture molto più complesse di essere creato.

Controllo assoluto sul layout della memoria, sull'allineamento e sull'accesso quando necessario. Se stai abbastanza attento puoi scrivere alcuni programmi molto compatibili con la cache. Per i programmi multiprocessore, puoi anche eliminare molti rallentamenti dai meccanismi di coerenza della cache.

(Okay, puoi farlo in C, assembly e probabilmente anche Fortran. Ma C ++ ti consente di scrivere il resto del tuo programma ad un livello superiore.)

Probabilmente questa non sarà una risposta popolare, ma penso che ciò che distingue C ++ sono le sue capacità di compilazione, ad es. template e #define. Puoi fare ogni sorta di manipolazione del testo sul tuo programma usando queste funzionalità, molte delle quali sono state abbandonate in lingue successive in nome della semplicità. Per me questo è molto più importante di qualsiasi gioco di basso livello che è presumibilmente più facile o più veloce in C ++.

C #, ad esempio, non ha una vera funzione macro. Non puoi #includere un altro file direttamente nel sorgente o usare #define per manipolare il programma come testo. Pensa a ogni volta che hai dovuto digitare meccanicamente codice ripetitivo e sapevi che c'era un modo migliore. Potresti anche aver scritto un programma per generare codice per te. Bene, il preprocessore C ++ automatizza tutte queste cose.

I "generici" la funzione in C # è similmente limitata rispetto ai modelli C ++. C ++ consente di applicare l'operatore punto a un modello di tipo T alla cieca, chiamando metodi (ad esempio) che potrebbero non esistere e i controlli di correttezza vengono applicati solo dopo che il modello è stato effettivamente applicato a una classe specifica. Quando ciò accade, se tutte le ipotesi fatte su T sono effettivamente valide, il codice verrà compilato. C # non consente questo ... tipo "T" fondamentalmente deve essere trattato come un oggetto, cioè utilizzando solo il minimo comune denominatore di operazioni disponibili a tutto (assegnazione, GetHashCode (), Equals ()).

C # ha eliminato il preprocessore e i veri generici, in nome della semplicità. Sfortunatamente, quando uso C #, mi ritrovo a cercare sostituti per questi costrutti C ++, che sono inevitabilmente più gonfiati e stratificati rispetto all'approccio C ++. Ad esempio, ho visto i programmatori aggirare l'assenza di #include in diversi modi gonfiati: collegamento dinamico ad assiemi esterni, ridefinizione di costanti in più posizioni (un file per progetto) o selezione di costanti da un database, ecc.

Come disse una volta la signora Crabapple di The Simpson, questo è "piuttosto zoppo, Milhouse."

In termini di Informatica, queste funzionalità di compilazione di C ++ consentono cose come il passaggio di parametri call-by-name, che è noto per essere più potente di call-by-value e call-by-reference.

Ancora una volta, questa non è forse la risposta popolare: qualsiasi testo introduttivo in C ++ ti avvertirà, ad esempio, di #define. Ma avendo lavorato con una grande varietà di lingue per molti anni e avendo preso in considerazione la teoria alla base di tutto ciò, penso che molte persone stiano dando dei cattivi consigli. Ciò sembra essere particolarmente vero nel sottocampo diluito noto come "IT."

Tecnicamente, penso che non ce ne sia davvero!

Onestamente non penso che ci sia qualcosa che il C ++ può fare, cosa che The D Language non può. Indipendentemente dalle capacità del C ++, è sempre più difficile e più disordinato di D o di qualsiasi altro linguaggio. Anche una cosa semplice come una dichiarazione di classe è molto più difficile e più caotica in C ++ rispetto a qualsiasi altra lingua.

L'unica cosa che C ++ può fare è essere compatibile con milioni di righe di codici già scritte in C ++.
Questa è l'unica cosa che nessun linguaggio diverso dal C ++ può fare :)

Passaggio di strutture POD tra processi con un sovraccarico minimo. In altre parole, ci consente di gestire facilmente BLOB di dati binari.

C # e Java ti costringono a mettere la tua funzione 'main ()' in una classe. Lo trovo strano, perché diluisce il significato di una classe.

Per me, una classe è una categoria di oggetti nel tuo dominio problematico. Un programma non è non un tale oggetto. Quindi non ci dovrebbe mai essere una classe chiamata 'Program' nel tuo programma. Ciò equivarrebbe a una dimostrazione matematica usando un simbolo per annotarsi - la dimostrazione - accanto a simboli che rappresentano oggetti matematici. Sarà solo strano e incoerente.

Fortunatamente, a differenza di C # e Java, C ++ consente funzioni globali. Ciò consente alla tua funzione main () di esistere all'esterno. Pertanto C ++ offre un'implementazione più semplice, più coerente e forse più vera del linguaggio orientato agli oggetti. Quindi, questa è una cosa che C ++ può fare, ma C # e Java non possono.

Penso che il sovraccarico dell'operatore sia una caratteristica piuttosto interessante. Naturalmente può essere molto maltrattato (come in Boost lambda).

Controllo rigoroso delle risorse di sistema (specialmente memoria) offrendo opzionalmente potenti meccanismi di astrazione. L'unico linguaggio che conosco che può avvicinarsi al C ++ in questo senso è Ada.

C ++ fornisce il controllo completo sulla memoria e, di conseguenza, rende il flusso dell'esecuzione del programma molto più prevedibile. Non solo puoi dire con precisione a che ora si verificano allocazioni e deallocazioni di memoria, ma puoi anche definire i tuoi propri cumuli, avere più cumuli per scopi diversi e dire esattamente dove sono allocati i dati della memoria. Ciò è spesso utile durante la programmazione su sistemi embedded / real time, come console di gioco, telefoni cellulari, lettori mp3, ecc ..., che:

  1. hanno limiti massimi di memoria che sono facili da raggiungere (costruisci con un PC che diventa più lento man mano che esaurisci la memoria fisica)
  2. spesso hanno un layout di memoria non omogeneo. È possibile che si desideri allocare oggetti di un tipo in un pezzo di memoria fisica e oggetti di un altro tipo in un altro pezzo.
  3. hanno vincoli di programmazione in tempo reale. Chiamare inaspettatamente il Garbage Collector al momento sbagliato può essere disastroso.

AFAIK, C e C ++ sono l'unica opzione sensata per fare questo tipo di cose.

Beh, ad essere sinceri, puoi fare qualsiasi cosa se sei disposto a scrivere abbastanza codice.

Quindi, per rispondere alla tua domanda, no, non c'è niente che non puoi fare in un'altra lingua che C ++ non può fare. È quanta pazienza hai e sei disposto a dedicare le lunghe notti insonni per farlo funzionare?

Ci sono cose che i wrapper C ++ rendono facile da fare (perché possono leggere i file di intestazione), come lo sviluppo di Office. Ma ancora una volta, è perché qualcuno ha scritto un sacco di codice per " a capo " per te in un RCW o "Runtime Callable Wrapper "

EDIT: ti rendi anche conto che questa è una domanda carica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top