Perché non possiamo creare oggetti banalmente costruibili usando malloc se il banale costruttore predefinito non esegue alcuna azione?


14

Ho difficoltà a comprendere il seguente paragrafo citato da cppreference su un banale costruttore predefinito. Ho cercato StackOverflow ma non ho ancora ricevuto una risposta chiara. Quindi per favore aiutatemi.

Un banale costruttore predefinito è un costruttore che non esegue alcuna azione. Tutti i tipi di dati compatibili con il linguaggio C (tipi POD) sono banalmente costruibili per difetto. A differenza di C, tuttavia, gli oggetti con banali costruttori predefiniti non possono essere creati semplicemente reinterpretando la memoria opportunamente allineata, come la memoria allocata con std :: malloc: il posizionamento-nuovo è necessario per introdurre formalmente un nuovo oggetto ed evitare potenziali comportamenti indefiniti.

In particolare, se il banale costruttore predefinito non fa nulla, perché non possiamo reinterpretare la memoria e far finta che ci sia un oggetto con il tipo specificato? Potresti fornire alcuni esempi del potenziale comportamento indefinito che ciò potrebbe causare?


Il lavoro più importante di un compilatore non è quello di compilare il codice sorgente ma di rifiutare il codice eventualmente non valido. Non può farlo quando si utilizza malloc ().
Hans Passant,

6
Il motivo è molto semplice. Meno opportunità ci sono per il programmatore di fare cose folli, più opportunità ci sono per il compilatore di fare cose folli (ottimizzazioni aggressive).
n. 'pronomi' m.

1
Per ragioni simili che non puoi proprio *reinterpret_cast<float*>(&someNonFloatObject) = 0.1f;. Il C ++ ha un concetto di oggetti e durata degli oggetti, specificato sulla macchina astratta, e solo perché non ci sono istruzioni CPU per creare un oggetto dalla memoria non significa che non ci siano differenze sulla macchina astratta.
Max Langhof,

1
@HansPassant Un compilatore che rifiuta tutto il codice rifiuta tutto il codice non valido. Ad ogni modo, non è compito del copiler rifiutare i programmi che hanno UB.
n. 'pronomi' m.

Risposte:


7

P0593R5 fornisce questo esempio:

struct X { int a, b; };
X *make_x() {
  X *p = (X*)malloc(sizeof(struct X));
  p->a = 1;
  p->b = 2;
  return p;
}

e spiega:

Se compilato con un compilatore C ++, questo codice ha un comportamento indefinito, poiché p-> un tentativo di scrivere su un oggetto secondario int di un oggetto X e questo programma non ha mai creato né un oggetto X né un oggetto secondario int.

Per [intro.object] p1,

Un oggetto viene creato da una definizione, da una nuova espressione, quando si modifica implicitamente il membro attivo di un'unione o quando viene creato un oggetto temporaneo.

... e questo programma non ha fatto nessuna di queste cose.

In pratica questo funziona e la situazione UB è considerata più come un difetto nello standard che altro. L'intero obiettivo del documento è di proporre un modo per risolvere il problema e casi simili senza rompere altre cose.


1

Per ragioni di "purezza".

L'alternativa e l' attuale status quo era che ogni area di archiviazione avrebbe contenuto tutti gli oggetti che si adattavano a quella memoria, contemporaneamente. Alcuni membri del comitato sono a disagio con lo status quo e molte persone temevano l'idea di avere infinitamente molti oggetti nello stesso posto (in uno stato virtuale, non inizializzato).

Nessuno è mai stato in grado di mostrare un problema logico con l'infinito numero di oggetti in una regione di archiviazione.

Poiché avevano diverse sezioni dello standard che dicevano cose contraddittorie, i membri del comitato hanno appena deciso di prendere sul serio una delle parti peggiori dello standard.

Inoltre, l'uso dei letterali stringa non è severamente consentito, se si prende davvero sul serio quella parte dello standard.


l'uso dei letterali stringa non è assolutamente consentito nei fatti. Esiste un problema CWG simile sugli type_infooggetti. Hai riferito di letterali stringa?
Avvocato linguistico,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.