PDA

Visualizza la versione completa : [C++] C vs C++


GliderKite
19-10-2010, 22:55
L'argomento riguarda in un certo senso il confronto tra i due linguaggi di programmazione C e C++. Ho letto diversi 3D sull'argomento, la maggior parte dei quali aveva come scopo la valutazione del "migliore" tra i due linguaggi, e come risposte sembravano andar molto di moda frasi del tipo: "un linguaggio migliore non esiste, dipende da cosa devi fare".

Ora, fatta questa doverosa premessa per evitare di dover leggere nuovamente le stesse risposte, tutto giusto, ma io non cerco di conoscere quale secondo i vostri pareri è il linguaggio migliore, ma essenzialmente due cose:

1) Quando (per quale ambiente/applicazione/etc...) si avrebbe un EFFETTIVO vantaggio dall'utilizzo di un linguaggio piuttosto che dell'altro.

2) In cosa il C++ potrebbe risultare realmente inferiore (sotto quale/i aspetti di QUALSIASI genere) rispetto al C.


Personalmente, ripeto: questa è solo una valutazione personale, trovo il C "superato", quindi perdonate la mia ignoranza quando dico che non conosco una vera motivazione per la quale sarei orientato a scegliere questo linguaggio rispetto all'altro, e da ciò nasce anche la mia curiosità che mi ha spinto ad aprire questa discussione. Se qualcuno può risolvere i miei dubbi gliene sarei grato.

Per ora è tutto.

MItaly
20-10-2010, 00:09
Da sostenitore del C++, ritengo che ci siano innumerevoli vantaggi rispetto al C; tuttavia il C ha comunque alcuni vantaggi; essendo un linguaggio molto semplice, è difficile che un compilatore contenga grossi bachi, per cui raramente si incontrano problemi di compatibilità tra un compilatore e l'altro; inoltre esistono compilatori C praticamente per ogni piattaforma, microcontrollori compresi. Il C++ invece necessita di un compilatore molto più complesso, e alcune caratteristiche (eccezioni, RTTI) richiedono anche un runtime più complesso rispetto a quello del C.
Inoltre il C++, proprio per alcune sue caratteristiche avanzate, nella maggior parte dei sistemi operativi può essere problematico da usare in ambiti quali la scrittura di driver kernel-mode; d'altra parte l'intero sistema operativo Haiku è scritto in C++, per cui se l'idea è fin dall'inizio di usare il C++ questi problemi si possono aggirare.
Uno dei punti più problematici è l'assenza di un'ABI definita; se per il C questo è facile (dopotutto si tratta semplicemente di decidere se mettere i parametri sullo stack in un verso o nell'altro, che registri usare e chi pulisce lo stack), per il C++ è molto più complesso, perché funzionalità come il polimorfismo (implementato solitamente tramite vtable), le eccezioni, RTTI e compagnia possono essere implementate in maniera differente da ogni produttore di compilatori, per cui la compatibilità tra librerie compilate con compilatori differenti è difficile da ottenere.

GliderKite
20-10-2010, 20:10
Quindi in pratica stai dicendo che l'unico aspetto che influenzerebbe la scelta riguarda la necessita di rendere più portabile il programma su piattaforme che, per via della maggior complessità di compilazione di un codice scritto in C++ (per la presenza di eccezioni, template, cast dinamici, etc..), potrebbero non riconoscere applicazioni compilate con differenti compilatori, o comunque ci sarebbe più difficoltà a trovare quella compatibilità necessaria.

E' preferibile mettere mano (se proprio si deve) al kernel utilizzando il C, ma come dici tu Haiku dimostra che non è necessariamente vero.


In che senso "Uno dei punti più problematici è l'assenza di un'ABI definita"?

In definitiva a meno di casi specifici che riguardano essenzialmente le problematiche che hai accennato, si può affermare che il C++ può soppiantare (in maniera non meno efficiente) il C?

p91paul
23-10-2010, 19:59
quello che so io è che per determinate cose il c può essere più veloce;
per esempio usare un array (int []) invece di un vector, su milioni di operazioni può dare qualche minima differenza di prestazioni.
lo stesso vale per cin e cout rispetto a scanf e printf.
inoltre non è detto che il c debba essere abbandonato perchè c'è il c++... io uso le classi però se devo usare un vettore metto un array e se lo devo allocare dinamicamente mi piace usare malloc e free piuttosto che new e delete...
così come se voglio scrivere su file preferisco la struttura FILE del c agli stream c++.

Infatti il bello del c++ è di supportare quasi interamente il c classico, che in alcuni casi può essere utile.

MItaly
24-10-2010, 13:26
Originariamente inviato da p91paul
quello che so io è che per determinate cose il c può essere più veloce;
per esempio usare un array (int []) invece di un vector, su milioni di operazioni può dare qualche minima differenza di prestazioni.
Dissento. Un vector, a dimensione fissata (caso in cui si può effettuare il confronto) ha la stessa identica velocità di un array allocato nell'heap tramite malloc o new, dato che l'operatore [] viene espanso in linea, e rispetto ad un vettore allocato sull'heap fornisce tutta una serie di facilities notevoli, tra cui l'espansione automatica e la distruzione automatica che mette al riparo dai memory leak.
Se invece vuoi un vettore sullo stack, c'è la classe std::array.


lo stesso vale per cin e cout rispetto a scanf e printf.
Solo perché lo standard impone che i due sistemi di IO siano sincronizzati di default (e quindi obbliga gli stream ad essere un layer ulteriore sopra gli stream C). Disattivando questa impostazione di compatibilità la velocità dovrebbe migliorare.


inoltre non è detto che il c debba essere abbandonato perchè c'è il c++... io uso le classi però se devo usare un vettore metto un array e se lo devo allocare dinamicamente mi piace usare malloc e free piuttosto che new e delete...
così come se voglio scrivere su file preferisco la struttura FILE del c agli stream c++.

Perché? :confused: Se scrivi in un linguaggio, usa gli strumenti che quel linguaggio ti mette a disposizione.


Infatti il bello del c++ è di supportare quasi interamente il c classico, che in alcuni casi può essere utile.
In alcuni casi, ma nella maggior parte dei casi la necessità di retrocompatibilità con il C ha reso il C++ un linguaggio molto peggiore di quanto non potesse essere.

GliderKite
24-10-2010, 13:54
..nella maggior parte dei casi la necessità di retrocompatibilità con il C ha reso il C++ un linguaggio molto peggiore di quanto non potesse essere.

Potresti ampliare questo discorso spiegando più in dettaglio il significato di questa frase?

MItaly
24-10-2010, 16:38
Originariamente inviato da GliderKite
Potresti ampliare questo discorso spiegando più in dettaglio il significato di questa frase?
Sto dicendo semplicemente che ci sono tutta una serie di caratteristiche ereditate dal C che rendono il C++ un linguaggio peggiore, in primis l'aver ereditato tutta la libreria standard C quando la si sarebbe dovuta abolire e sostituire con qualcosa di più orientato agli oggetti, o quantomeno si sarebbero dovute abolire le funzionalità duplicate e abrogare tutte le funzioni non rientranti ( :dhò: ); l'uso delle stringhe C di default nelle funzioni di libreria poi è una pessima idea, dal momento che la loro gestione è complessa e inefficiente.
Si sarebbe dovuto fornire fin dall'inizio un supporto adeguato agli smart pointers per disincentivare l'uso dei puntatori "liberi", che non rendono evidente chi è il proprietario dell'oggetto in questione.
La move semantic sarebbe dovuta esistere fin da subito, in modo da rendere più efficiente l'utilizzo dei container STL come tipo restituito dalle funzioni. L'uso degli array stile C sarebbe dovuto essere disincentivato.
Il precompilatore avrebbe dovuto rivestire un ruolo molto meno importante di quello che ha , e soprattutto si sarebbe dovuto trovare un modo per abolire il demenziale sistema dei prototipi e degli header.
Inoltre la grammatica C++ sarebbe dovuta essere più semplice, in modo da consentirne il parsing in tempi umani.
Naturalmente quello che dico è difficile che si potesse avverare, se non altro perché ai tempi molte tecniche attuali (ad esempio appunto gli smart pointers) non erano state neanche immaginate.

L'errore fondamentale che vedo spesso nell'utilizzo del C è che molti lo considerano come un "C con classi". Sbagliato, completamente sbagliato, il fatto che sia retrocompatibile con il C non vuol dire che tu lo debba usare come il C. Il C++ è un linguaggio diverso, ha delle sue "espressioni idiomatiche" differenti e ci si lavora in maniera diversa rispetto al C, un programma C++ moderno non dovrebbe contenere neanche una stringa C, un puntatore libero, una chiamata a delete, la gestione della memoria andrebbe effettuata sempre con gli smart pointers e in generale la gestione delle risorse tramite l'idioma RAII, che è a costo zero (in termini di overhead) ed evita tutte le grane di memory e resource leak.

Per avere un'idea di cosa intendo per un "C++ migliore", dai un'occhiata al D (http://www.digitalmars.com/d/).

Paulin
26-10-2010, 16:04
Originariamente inviato da GliderKite 1) Quando (per quale ambiente/applicazione/etc...) si avrebbe un EFFETTIVO vantaggio dall'utilizzo di un linguaggio piuttosto che dell'altro.

2) In cosa il C++ potrebbe risultare realmente inferiore (sotto quale/i aspetti di QUALSIASI genere) rispetto al C.

Io ho iniziato studiando il C++ e programmando in C++, oggi sto sviluppando solo in C. É una prova che sto facendo, per ora mi trovo bene, per i seguenti motivi:

Compilatore mooolto più leggero e veloce.

So cosa fa il mio codice a livello macchina.

Il linguaggio mi sembra più semplice e ci sono meno strade per fare una stessa cosa rispetto al C++, così perdo meno tempo a valutare una scelta piuttosto che un'altra.



Oltre le cose che sono già state dette ci sono altre considerazioni che potrei fare sui due linguaggi:

Gli applicativi generati dai due linguaggi hanno quasi le stesse prestazioni a patto che nel C++ non si faccia un eccessivo uso delle funzionalità proprie del C++, quali polimorfismo, ereditarietà multipla, funzioni virtuali, ecc. In tal caso Il C++ potrebbe originare applicativi con prestazioni inferiori rispetto al C.

Lo studio del C++ è lungo e la sua perfetta padronanza è difficile, mentre il C è un po' più semplice e immediato.

Il C++ è preferito per lo sviluppo di grandi progetti realizzati in team per la sua modularità e la possibilità di mantenimento. Personalmente ritengo che con un buon IDE e adottando una buona struttura modulare ciò sia possibile anche con il C.

Il C è ancora indispensabile per la programmazione diretta dei dispositivi, ad esempio per i drivers, tuttavia un codice in linguaggio C può essere ancora scritto su un compilatore C++.

Il C non è morto, l'ultima implementazione è il C99 ed è correntemente mantenuto e migliorato.

GliderKite
26-10-2010, 18:34
Che io sappia, per quanto riguarda l'utilizzo di strutture dati base (tipiche del C) rispetto all'utilizzo delle strutture dati offerte dalla STL, la scelta tra un array C-style piuttosto che l'utilizzo di un vector è da favorirsi comunque quando si ha a che fare con dimensioni non eccessivamente grandi e soprattutto quando si intende utilizzare un allocazione statica della memoria, poichè i vector si basano sull'allocazione/deallocazione dinamica della memoria e ciò comporta in ogni caso una minor efficienza.

Invece per quanto riguarda l'utilizzo di allocatori automatici, come possono essere gli smart-pointer, questi sono meno efficienti dei "normali" puntatori in quanto devono garantire la mutua esclusione delle operazioni.

Io non ho mai considerato il C come un linguaggio morto, ma ritengo che un utilizzo completo del C++ si rilevi essere migliore quando i progetti iniziano a diventare sempre più grandi. E, nonostante il fatto che alcune caratteristiche base del C++ (come e soprattutto l'utilizzo delle eccezioni) possano minare l'efficienza dell'applicazione, a mio parere il linguaggio stesso rispecchia, o meglio, da la possibilità di scrivere un "buon codice", grazie anche al paradigma OOP.

Senza contare che, nonostante il discorso di MItaly riguardo ad un "C++ migliore" se non si fosse mantenuta una piena compatibilità con il C (il che molto probabilmente è vero), tutt'oggi l'utilizzo del C++, come tutti sappiamo, consente anche lo sfruttamento di quelle che sono le migliori caratteristiche del C (ad esempio un buon codice sorgente C++ potrebbe contenere funzioni come fread/fwrite, più efficienti rispetto alle read/write).

MItaly
26-10-2010, 22:25
Originariamente inviato da GliderKite
Che io sappia, per quanto riguarda l'utilizzo di strutture dati base (tipiche del C) rispetto all'utilizzo delle strutture dati offerte dalla STL, la scelta tra un array C-style piuttosto che l'utilizzo di un vector è da favorirsi comunque quando si ha a che fare con dimensioni non eccessivamente grandi e soprattutto quando si intende utilizzare un allocazione statica della memoria, poichè i vector si basano sull'allocazione/deallocazione dinamica della memoria e ciò comporta in ogni caso una minor efficienza.
Solo al momento dell'allocazione; e, come detto, std::array consente di avere array allocati sullo stack.


Invece per quanto riguarda l'utilizzo di allocatori automatici, come possono essere gli smart-pointer, questi sono meno efficienti dei "normali" puntatori in quanto devono garantire la mutua esclusione delle operazioni.
Dipende dal tipo di smart pointer. Uno scoped_ptr/unique_ptr (che vanno bene nella stragrande maggioranza dei casi, dove serve semplicemente semantica RAII per una risorsa locale) ha virtualmente zero overhead.


E, nonostante il fatto che alcune caratteristiche base del C++ (come e soprattutto l'utilizzo delle eccezioni) possano minare l'efficienza dell'applicazione,
Al di là di un leggero aumento delle dimensioni dell'eseguibile, le eccezioni "costano" solo nel momento in cui sono sollevate. Per il resto, se non sono sollevate quasi mai, sono anche più efficienti dell'approccio a codici restituiti perché non ci deve essere un if ad ogni chiamata a funzione, è cioè il codice del throw che si va a cercare l'handler, non c'è del codice che controlla ad ogni momento se non si è verificato un errore.


Senza contare che, nonostante il discorso di MItaly riguardo ad un "C++ migliore" se non si fosse mantenuta una piena compatibilità con il C (il che molto probabilmente è vero), tutt'oggi l'utilizzo del C++, come tutti sappiamo, consente anche lo sfruttamento di quelle che sono le migliori caratteristiche del C
Più che altro ha contribuito al suo successo il fatto di poter integrare facilmente codice legacy e di consentire a molti programmatori C di credere di saper programmare in C++.

(ad esempio un buon codice sorgente C++ potrebbe contenere funzioni come fread/fwrite, più efficienti rispetto alle read/write).
Scusa la pignoleria, ma read/write (se si parla delle syscall POSIX) di base dovrebbero essere leggermente più veloci delle relative funzioni di libreria C, dal momento che si salta un livello di astrazione.

Loading