2015-01-28 13 views
15

consideri seguente esempio di base:Omettendo un comportamento non definito di dichiarazione di ritorno in C89 (noto anche come ANSI C)?

#include <stdio.h> 

int main(void) 
{ 
    printf("Hi there!\n"); 
} 

vuol invocano un comportamento indefinito in C89? Ho cercato di ottenere un po 'di senso da this question, ma le risposte più avanzate hanno affermato che è definito dall'implementazione e sicuramente nessun UB qui (con commenti di Keith Thompson, che sembra contraddittorio).

La specifica dice nel §3.16 Definizioni e convenzioni:

Se un “deve” o “non deve” requisito che appare al di fuori di un vincolo è violata. il comportamento non è definito. Il comportamento non definito è altrimenti indicato in questo standard internazionale dalle parole "comportamento non definito" o dall'omissione di qualsiasi definizione esplicita del comportamento . Non c'è differenza di enfasi tra questi tre: sono tutti che descrivono "comportamento non definito".

e §5.1.2.2.3 terminazione Programma:

Un ritorno dalla chiamata iniziale alla funzione main equivale a chiamare la funzione exit con il valore restituito dalla funzione main come argomento. Se la funzione main esegue un ritorno che specifica alcun valore, lo stato della terminazione restituito all'ambiente host è indefinito.

mia comprensione è che quest'ultimo sottoclausola non copre caso di ritorno mancante, come return dichiarazione non mai invocato, in tal modo si applica l'ex sottoclausola.

lettura Tuttavia futher indica qualcosa di diverso, §6.6.6.4 Il return dichiarazione:

Se viene eseguita un'istruzione return, senza espressione, e il valore della chiamata di funzione è utilizzato dal chiamante , il comportamento non è definito. Il raggiungimento dello } che termina una funzione equivale all'esecuzione di un'istruzione senza un'espressione.

Ok, ora 5.1.2.2.3 subclause vale:

Se la funzione main esegue un ritorno che specifica alcun valore. lo stato della terminazione restituito all'ambiente host è indefinito.

Il termine "stato di terminazione non è definito" non sembra essere UB, nè qualsiasi comportamento specifico, ma più come se fosse al di fuori del campo di applicazione di C standard, pensando più simile a: "lasciate che l'ambiente host per essere preoccupati, ci laviamo le mani da qui ". E 'corretta interpretazione?

+1

Se non l'hai già visto, ecco alcune risposte interessanti: http: // StackOverflow.it/q/204476/3933332 – Rizier123

+1

[La mia bozza C89] (http://port70.net/~nsz/c/c89/c89-draft.html) non corrisponde affatto alle virgolette " ve dato. I numeri delle sezioni sono completamente diversi e anche il testo corrispondente differisce. Certo, è una bozza, non lo standard finale. Tuttavia, non possiamo concordare una risposta se non siamo d'accordo sullo standard. –

+2

Ho letto che sta dicendo che è equivalente a chiamare 'return' senza espressione, che quindi per' §5.1.2.2.3' afferma che un 'return' senza espressione restituisce un codice di ritorno indefinito al sistema operativo dell'host. Hai ragione, questo non è un comportamento indefinito per dire, poiché ciò che accade è conosciuto e sempre lo stesso; il programma terminerà e un valore verrà restituito al sistema operativo come codice di ritorno. Ciò che * è * indefinito è ciò che sarà quel valore. Quindi sì, direi che la tua interpretazione è corretta. – aruisdante

risposta

4

anni fa ho effettivamente risolto i problemi causati da questo. Diventa ancora più interessante se si dispone di alcuni percorsi di codice con resi e altri senza.

Come ha affermato @aruisdante nei commenti, il comportamento mostrato è effettivamente "indefinito", ma l'unica parte non definita è il valore restituito (non è come molte altre situazioni "non definite" che potrebbero causare il blocco del programma).

In questi giorni ciò equivale a un rischio per la sicurezza poiché il valore "non definito" restituito è in genere qualsiasi cosa si trovi nel registro CPU normalmente utilizzato per restituire valori (o in pila in alcune implementazioni), che potrebbe essere teoricamente utilizzato per perdere dati sensibili.

+0

Ti riferisci specificamente alla funzione 'main' o a una funzione ordinaria? – Rufflewind

+0

IIRC, era 'main', ma era di nuovo nei primi anni '90. Questo è stato molto tempo fa. – James

2

Credo che l'intento del Comitato standard fosse che questo valore dello stato di terminazione non è specificato.

Secondo N739 progetto:

e modificare l'ultima frase del 5.1.2.2.3 sottoclausola da:

Se la principale/funzione/esegue un ritorno che specifica alcun valore, la terminazione lo stato restituito all'ambiente host è non definito.

a:

Se la principale/funzione/esegue un ritorno che specifica alcun valore, | lo stato di terminazione restituito all'ambiente host è non specificato.

[Il concetto di valore indefinito è accuratamente evitato altrove.]

È inoltre possibile trovare in ulteriori standard, che la terminologia è stata modificata e la durata "non specificato" viene utilizzato di conseguenza.

Direi che non è assolutamente inteso essere un comportamento indefinito di per sé, ma è ancora impossibile decidere se si tratta di un comportamento non specificato o come ho detto di non avere alcun comportamento. Altro brano, che indicherebbe quest'ultimo questi è §1 Ambito:

La presente norma internazionale non specifica:

  • il meccanismo con cui i programmi C sono invocati per l'uso da un sistema di elaborazione dei dati ;

mi aspetterei questo significa anche che la presente norma internazionale non specifica come stato di terminazione dei programmi è gestita da ambiente host.

Problemi correlati