Non posso dirvi le specifiche della vostra piattaforma perché non lo conosco, ma c'è una risposta generale al comportamento che si vede.
Quando la funzione che ha un ritorno è compilata, il compilatore utilizzerà una convenzione su come restituire quei dati. Potrebbe essere un registro di macchina o una posizione di memoria definita, ad esempio tramite uno stack o qualsiasi altra cosa (anche se in genere vengono utilizzati registri di macchina). Il codice compilato può anche usare quella posizione (registro o altro) mentre si fa il lavoro della funzione.
Se la funzione non restituisce nulla, il compilatore non genererà il codice che riempie esplicitamente tale posizione con un valore di ritorno. Comunque, come ho detto sopra, può usare quella posizione durante la funzione. Quando scrivi un codice che legge il valore di ritorno (ch2 = toUpper(ch);)
, il compilatore scriverà il codice che usa la sua convenzione su come recuperare quel ritorno dalla posizione convenzionale. Per quanto riguarda il codice del chiamante, leggerà quel valore dalla posizione, anche se non è stato scritto esplicitamente lì. Quindi ottieni un valore.
Ora osservate l'esempio di @ Ray, il compilatore ha utilizzato il registro EAX per archiviare i risultati dell'operazione di alloggiamento superiore. Succede, questa è probabilmente la posizione in cui vengono scritti i valori di ritorno. Sul lato chiamante ch2 è caricato con il valore che è in EAX - quindi un ritorno fantasma. Questo è vero solo per la gamma di processori x86, in quanto su altre architetture il compilatore può utilizzare uno schema completamente diverso nel decidere come organizzare la convenzione
Tuttavia, i buoni compilatori cercheranno di ottimizzare in base al set di condizioni locali, conoscenza di codice, regole e euristica. Quindi una cosa importante da notare è che questa è solo fortuna che funzioni. Il compilatore potrebbe ottimizzare e non fare questo o altro - non dovresti rispondere al comportamento.
fonte
2011-09-02 08:28:13
odora di comportamento non definito. – ThiefMaster
@ThiefMaster: It ** è ** UB. È semplicemente fortunato che il registro in cui normalmente viene inserito il valore di ritorno viene utilizzato anche per la sottrazione. –
Grazie per tutti :) – harrison