2016-03-01 19 views
12

Supponiamo che il tuo software funzioni solo su due complementi di macchine in cui il comportamento di overflow firmato è ben definito. L'overflow firmato è ancora un comportamento indefinito in C e C++ e il compilatore è libero di sostituire l'intero programma con "ret", avviare una guerra nucleare, formattare l'unità o far volare via demoni dai demoni.Il comportamento non definito si applica al codice asm?

Supponiamo che tu abbia overflow firmato in asm in linea, il tuo programma invoca ancora UB?

Se sì, che dire assemblatore compilato e collegato separatamente?

+0

Questa è una domanda molto interessante. Voglio sapere anche io. – callyalater

+5

Inline asm anche standard C o C++ in primo luogo? Onestamente non lo so. In caso contrario, l'intera domanda si trova su un terreno instabile che sento. –

+2

Bene c'è [dcl.asm]: * La dichiarazione 'asm' è supportata in modo condizionale; il suo significato è definito dall'implementazione. * – NathanOliver

risposta

8

"Comportamento non definito" indica il C resp. Gli standard C++ non definiscono il comportamento del tuo programma. Se il tuo programma contiene assembly inline, dovrebbe essere abbastanza chiaro che il suo comportamento non sarà normalmente descritto dallo standard C o C++. Alcuni altri standard potrebbero anche definire il comportamento, ma ciò non significa ancora "comportamento definito" nel contesto dello standard C o C++.

Detto questo, lo standard C richiede documentazione delle estensioni supportate. Se il comportamento del programma si può dedurre dalla documentazione del implementazione e l'implementazione rende il vostro programma di comportarsi in modo diverso, che è un fallimento della vostra implementazione di conformarsi allo standard:

4. Conformità

8 Un'implementazione deve essere accompagnata da un documento che definisca tutte le caratteristiche definite dall'implementazione e specifiche della locale e tutte le estensioni.

Per C++, questo requisito è stato attenuato: conformità

1,4 Attuazione [intro.compliance]

9 Ciascuno di esecuzione comprende documentazione che identifica tutti i costrutti condizionalmente supportati che non supporta e definisce tutte le caratteristiche specifiche della locale.

e

1,9 L'esecuzione del programma [intro.execution]

2 Certi aspetti e le operazioni della macchina astratta sono descritti nella presente norma internazionale come definito dall'implementazione [... ] Ogni implementazione deve includere una documentazione che descriva le sue caratteristiche e il suo comportamento in questi aspetti. [...]

Non riesco a trovare un requisito per le estensioni da documentare e, se documentato, per essere documentato correttamente. Ciò suggerirebbe che in C++, anche se la tua implementazione definisce il comportamento del tuo programma come un'estensione, se risulta che la documentazione è sbagliata, è semplicemente un peccato.

Per la dichiarazione semi-standard C++ asm (come menzionato nei commenti, "La dichiarazione asm è supportata in modo condizionale, il suo significato è definito dall'implementazione."), Se l'implementazione lo supporta è necessario che sia documentato, ma naturalmente è prassi comune che le implementazioni supportino l'assemblaggio in linea in modo diverso da quanto suggerito dallo standard C++, quindi questo non ti dà molto di più.

+0

Ok, quindi secondo lo standard è stata definita l'implementazione di ciò che asm inline significa per il programma. Ciò pone quindi la domanda, cosa fanno in realtà i compilatori popolari? – Eloff

+0

@Eloff Questa è una domanda molto diversa da quella che hai chiesto in questo e richiede troppo per rispondere qui. – hvd

3

Appena si afferma di aver firmato overflow in linea asm, vuol dire che si sta parlando di un particolare compilatore (o di una serie di compilatori) perché in C come in C++ il supporto per la dichiarazione asm e il suo significato sono Compilatore definito.

Se il compilatore definisce la parola asm consentendo l'inserimento diretto del codice assembly nella sua uscita e se la macchina consente firmato overflow, quindi un overflow firmato nella asm inline è perfettamente definito per tale compilatore e quella macchina: it è ciò che il processore darà come risultato. Dovresti comunque controllare se può generare una rappresentazione trap per un intero con segno, ma in ogni caso è definito. L'unico caso che finirebbe in UB sarebbe quando il compilatore dice che alcune rappresentazioni nel numero intero con segno causeranno un comportamento indefinito. Ma io non conosco nessuno che faccia e tu sei già nel contesto di un insieme definito e finito di compilatori e macchine.

La compilazione separata di un modulo di assemblaggio e codice C e/o C++ sarebbe la stessa per quella serie di compilatori e macchine: il risultato è definito dall'implementazione che non è lo stesso di UB.

Un altro esempio di qualcosa che è esplicitamente implementazione definiti negli standard (sia C e C++) è se char tipo è firmato o no: se non si sa cosa compilatore che si utilizza, non si può fare affidamento su di essa, ma come non appena si sceglie un'implementazione del compilatore, tale implementazione è necessaria per dire se è firmata o non firmata, ed è non comportamento indefinito, il che significa che il compilatore non può sostituire il codice completo con un ret, ad esempio.