2009-07-07 10 views
10

Ho sentito molte volte quella frase di Bjarne Stroustrup "C++ rende più difficile spararti ai piedi, ma quando lo fai, si toglie l'intera gamba" e non so davvero se sia terribile come sembra.Qual è la caratteristica più pericolosa del C++?

Qual è la cosa peggiore che ti sia mai capitata (o più correttamente, nel tuo software) durante la programmazione in C++? In che modo può essere più pericoloso di dire semplicemente C, per esempio?

+3

Ogni volta che si è consapevoli di ciò che si sta facendo non c'è nulla di pericoloso. La pistola nelle mani di scimmia può sempre portare a guai. –

+3

Sì, ma la banana porta molto meno. –

+0

Non ti darò una risposta, ma ti dirò il consiglio più memorabile che abbia mai sentito sull'argomento. Cioè, "se ti dimentichi di prendere un'eccezione, l'intera applicazione uscirà!". Per qualche ragione, a me quel momento mi sembrò molto sinistro. –

risposta

11
delete [] array; 

a volte può diventare

delete array; 

nelle mani di qualcuno che non conosce. Rilevare che il bug in giù può succhiare in modo orribile, e non accade quando stai facendo malloc e gratis.

+1

Come probabilmente sapete, perché non succede con malloc e free è perché non fa distinzione tra un array o un singolo oggetto. – Skurmedel

+1

Esattamente. Così mi sono sbarazzato della clausola 'sembra di' lì; Ero cauto perché è passato così tanto tempo da quando ho usato C ... – mmr

+0

Hehe qui :) – Skurmedel

1

L'implementazione della gestione delle eccezioni è un modo semplice per individuare perdite di memoria.

+0

Come mai? Stai pensando al caso delle eccezioni lanciate dal puntatore invece del riferimento? –

+2

Con RAII corretto, questo non è un problema, penso che sia –

+0

in disaccordo. Non vedo ragioni per cui la memoria sia trapelata con eccezioni. Lo standard è molto chiaro su come l'eccezione è propogata. –

0

Probabilmente l'aspetto più pericoloso C++ che non esiste in C è la possibilità di ignorare operatori per tipi complessi. Ad esempio, può essere molto semplice eseguire l'aggiunta alla sottrazione (e viceversa).

È stupido che chiunque voglia fare do, ma può essere fatto. Rendendolo pericoloso.

4

Il requisito del distruttore virtuale è facile per i nuovi venuti a mancare (anche se penso che la maggior parte dei compilatori sia abbastanza intelligente da indicarlo fuori).

+0

Quale requisito di distruttore virtuale? – ralphtheninja

+0

@Magnus: se si distrugge un oggetto tramite un puntatore alla sua base (o qualsiasi antenato), se il distruttore non è virtuale verrà chiamato il distruttore errato. Quindi le classi progettate per essere sovrascritte dovrebbero probabilmente avere un distruttore virtuale. –

2

Operator overloading. È molto facile rendere le cose difficili da capire cosa sta succedendo. È facile trascurare il fatto che si sta verificando un sovraccarico, anche per sviluppatori C++ esperti.

+7

Gli operatori sovraccaricati hanno il loro posto. Non direi che la funzione è intrinsecamente cattiva - può essere abbastanza utile. È quando le persone iniziano a definirle per fare cose in modo intuitivo che emergono le difficoltà. Gli operatori sovraccaricati, se usati correttamente, possono rendere il codice più semplice e pulito. –

0

Se stai per confrontare la sicurezza di C++ contro C, hai perso il punto di quella frase. C++ è probabilmente non più sicuro di C.

Dove il confronto può davvero essere fatto è con un linguaggio come Java. Essenzialmente, Java gestisce la tua memoria per te, così non finirai con un comportamento indefinito quando chiami memoria al di fuori della memoria che il tuo programma sta attualmente utilizzando (andando fuori limite su array, ecc.).

Per rispondere alla tua domanda, però, la cosa peggiore che mi sia capitata era un buffer overflow per ignorare la mia password (l'ho fatto di proposito, comunque).

+0

Molto vero. Gli aspetti più pericolosi di C++ sono in realtà gli holdovers di C. Ci sono alcune funzionalità in C++ che non esistono in C (come l'overloading dell'operatore); Credo che la domanda sia chiedere a quelli. – Randolpho

+0

In effetti il ​​controllo di tipo statico può essere applicato più rigorosamente in C++ che in C, penso (i typedef alla fine sono qualcosa come "tutto va") – fortran

+2

C++ ti dà la scelta, puoi usare i limiti dell'array controllato se vuoi - ma non è necessario (e pagare la penalità di prestazioni) se non è necessario per –

0

Mi sono sempre chiesto di questa citazione. Non riesco a pensare a un modo in cui C++ è più pericoloso di C.

In ogni caso, devo dire la "caratteristica" più pericoloso è che non c'è nulla che impedisca di accedere alla memoria non allocato. È un errore che è quasi impossibile eseguire il debug, causa ogni sorta di comportamento casuale, dagli arresti anomali al nulla al solo comportamento strano.

2

Ho passato questo a una funzione di supporto in un altro oggetto da un costruttore. La funzione helper ha aggiunto il puntatore a un elenco di oggetti che stava mantenendo.Naturalmente, dopo che il costruttore ha terminato e restituito, l'oggetto si trovava in una posizione molto diversa nella memoria e il puntatore memorizzato nell'altro oggetto non era più valido. Yikes!

+0

È vero? : - | – fortran

+2

Non è mai sicuro perdere "questo" da un costruttore. Soprattutto non in un ambiente multi-thread, nel qual caso l'oggetto può essere parzialmente costruito o solo parzialmente visibile .. Gli oggetti non possono essere considerati completamente costruiti fino a dopo che il costruttore è tornato (questo vale anche per Java e C#). –

+0

Sembra che tu abbia avuto un bug. –

0
  • sovraccarico dell'operatore se non correttamente implementato
  • ereditarietà multipla (facile abusare)
  • buffer overflow
2

avrei dire conversione automatica. C++ può creare variabili temporanee in modi non intuitivi attraverso la conversione automatica dei tipi.

Problemi correlati