2015-07-16 2 views
11

Questo è un esperimento mentale, non un codice di produzione né uno stile di codifica valido.Questo codice C ha un comportamento definito?

Supponiamo di avere questa funzione

int find_process_pid_by_name(char* name, int* threads_in_process); 

che restituiscono il PID di un processo chiamato e anche sempre memorizzare nella threads_in_process il numero di thread in esecuzione in detto procedimento.

Un programmatore pigro, interessati solo sulla PID, scrive questo codice

int pid = find_process_pid_by_name("a process name", &pid); 

vuol innescare un comportamento indefinito?

+0

Suppongo che accedendo a 'threads_in_process [i], i = 1,2,3..' nella funzione' find_process_pid_by_name' che sarà un comportamento indefinito! – user007

+0

È ben definito. Come menzionato nelle risposte, c'è un punto di sequenza giusto prima che la funzione ritorni, il che significa che qualsiasi precedente effetto collaterale è avvenuto. –

+1

Strettamente, si passa un 'const char *' a una funzione che accetta un 'char *'; se la funzione modifica ciò che viene passato, si ottiene un comportamento indefinito. –

risposta

10

No, non penso che sia un comportamento indefinito. C'è un punto di sequenza immediatamente prima che la funzione venga chiamata (dopo che gli argomenti e l'espressione che denota la funzione chiamata sono stati valutati), e ce n'è un altro prima che la funzione chiamata ritorni. Eventuali effetti collaterali su pid eseguiti dalla funzione chiamata sono stati completati prima che la funzione termini la restituzione. Il risultato della funzione viene quindi assegnato a pid. Non c'è alcuna domanda sulla posizione a cui è stata assegnata la modifica della funzione. Non vedo nulla che invochi un comportamento indefinito.

Suppongo che la funzione chiamata tratti l'argomento int * come puntatore di sola scrittura su un valore singolo. Se si legge da un singolo valore, è necessario sapere che pid è stato inizializzato in precedenza (formalmente, in pratica, non importa). Nel contesto, pid non è stato inizializzato; il risultato della funzione lo inizializzerà. Quindi, se la funzione legge dal suo argomento puntatore, tecnicamente, hai un comportamento indefinito. Se la funzione considera il puntatore come l'inizio di un array a più elementi e accede oltre l'elemento zeroth, ci sono dei problemi. Ma queste sono alcune questioni al di fuori dell'ambito previsto della domanda/discussione.

1

Sì, credo che questo codice sia ben definito. C'è un punto di sequenza alla fine della funzione, prima che il valore di ritorno venga copiato nel contesto di chiamata. Quindi la funzione assegnerà prima a pid indirettamente tramite threads_in_process, quindi ritornerà, quindi il valore restituito verrà assegnato a pid.