2014-12-26 15 views
5

Capisco che se a printf non viene fornito alcun argomento, viene generato un valore imprevisto.Printf senza spiegazione degli argomenti

Esempio:

#include <stdio.h> 

int main() { 
    int test = 4 * 4 

    printf("The answer is: %d\n"); 
    return 0; 
} 

Ciò restituisce un numero casuale. Dopo aver giocato con diversi formati come% p,% x ecc, non stampa 16 (perché non ho aggiunto la variabile alla sezione argomento) Quello che mi piacerebbe sapere è, dove vengono presi questi valori a partire dal? È la cima della pila? Non è un nuovo valore ogni volta che compilo, il che è strano, è come un valore fisso.

+2

È un comportamento non definito. Il fatto che sembri risolto è un felice incidente. Potrebbe provenire dallo stack, magari da un registro ... non si sa, non dovrebbe importare o contare su di esso. –

+0

1. Con 'printf (" La risposta è:% d \ n ")', stai passando ** un argomento **. 2. Se quell'argomento punta a una stringa con terminazione null che non contiene un carattere '%', quindi 'printf' genererà un valore ben previsto. –

risposta

5
printf("The answer is: %d\n"); 

richiama il comportamento non definito. C richiede un identificatore di conversione per avere un argomento associato. Mentre è un comportamento indefinito e qualsiasi cosa può accadere, sulla maggior parte dei sistemi finisci per scaricare lo stack. È il tipo di trucco utilizzato in format string attacks.

4

Si chiama undefined behavior ed è spaventoso (vedere this answer).

Se si desidera una spiegazione, è necessario immergersi nei dettagli specifici dell'implementazione. Quindi studia il codice sorgente generato (ad es. Compila con gcc -Wall -Wextra -fverbose-asm + i tuoi flag di ottimizzazione, quindi guarda nel file di assemblaggio generato) e il ABI del tuo sistema.

+0

Aha, adoro la risposta che hai fornito. E va bene, andrò a ispezionare quello allora. – sbnation

1

Printf è una funzione di argomento variabile. La maggior parte dei compilatori inserisce gli argomenti nello stack e quindi chiama la funzione, ma, a seconda della macchina, del sistema operativo, della convenzione di chiamata, del numero di argomenti e così via, ci sono anche altri valori inseriti nello stack, che potrebbero essere costanti nella tua funzione.

Printf legge questa area di memoria e la restituisce.

2

La funzione printf andrà alla ricerca dell'argomento nello stack, anche se non ne viene fornito uno. Verrà usato tutto ciò che è lì, se non riesce a trovare un argomento intero. La maggior parte delle volte, otterrai dati privi di senso. I dati scelti variano in base alle impostazioni del compilatore. Su alcuni compilatori, potresti addirittura ottenere 16 come risultato.

Ad esempio:

int printf(char*, int d){...} 

questo sarebbe come printf opere (non proprio, solo un esempio). Non restituisce un errore se d è nullo o vuoto, guarda solo sullo stack per l'argomento che dovrebbe essere lì da visualizzare.

+0

Su alcuni ABI, le funzioni variadiche sono invocate in modo diverso rispetto alle funzioni di tipo fisso-aritmetico. –

Problemi correlati