Chi riceve il valore restituito da main ()?


34

So che nei computer, il valore restituito dalla main()funzione viene ricevuto dal sistema operativo. Ma cosa succede nella main()funzione di un microcontrollore?


7
Uso sempre void main () quando utilizzo C per i microcontrollori PIC. Quando si usano compilatori C per microcontrollori, non importa davvero. Perché non esiste un sistema operativo che esegue (dire) "main.c". Se c'è qualcosa come RTOS in esecuzione in quel microcontrollore, il sistema operativo è "main.c".
Abdullah Kahraman,

4
Non proprio un duplicato, ma almeno correlato: electronics.stackexchange.com/q/30830/4950
PetPaulsen

1
Il modo in cui viene definita la funzione di avvio di solito non spetta a voi decidere. L'ambiente in uso documenterà i moduli delle funzioni di avvio supportate. Le implementazioni C ospitate sono necessarie per supportare due forme maincon due firme diverse, entrambe restituite int. Se si utilizza un'implementazione C indipendente, tale implementazione determina come scrivere la funzione di avvio. Non puoi scrivere una voidfunzione di ritorno solo perché non ritorna. Il comportamento di non ritorno è diverso dal tipo di funzione che influenza le convenzioni generali di chiamata.
Kaz,

Risposte:


42

Su un microcontrollore, main()non ci si aspetta che esca mai, e il comportamento se non lo è, quindi spetta a chiunque abbia scritto il runtime C per il microcontrollore. Ho visto sistemi che:

  • Avere un loop implicito in giro main(), in modo che se esce, viene semplicemente richiamato.
  • Avere un semplice ciclo "jump-to-self" che viene eseguito se main()mai esce.
  • Basta eseguire il resto della memoria del codice che segue la chiamata a main(). Questo si chiama "scappare tra le erbacce".

Non ne ho mai visto uno che effettivamente fa qualcosa con il valore restituito da main(). Se questo è qualcosa a cui tieni davvero, allora dovresti dare un'occhiata - e possibilmente modificare - il codice sorgente per la libreria di runtime C del tuo sistema.


1
Mi hai battuto sul tempo. +1 per la sincronicità.
Adam Lawrence,

9
Lo standard C che definisce main()un intvalore di ritorno ovviamente non è stato progettato pensando a un microcontrollore senza OS. Quindi questo è un comportamento non specificato e tutto potrebbe accadere a seconda del runtime C, come elencato da Dave.
ndim,

4
C in esecuzione su un microcontrollore senza OS potrebbe essere considerato un'implementazione indipendente e lo standard C non richiede nemmeno che un ambiente indipendente abbia un valore main(), e tanto meno definito, il suo valore di ritorno. Dipende dall'implementatore.
KutuluMike

2
@ndim: dividere i peli, void main( void )è un comportamento definito dall'implementazione , non un comportamento non specificato .
Andrew,

1
@MichaelEdenfield: Davvero. Tuttavia, tutto il codice in C è definito in termini di funzioni, quindi non è mai possibile avere un sistema di fresstanding completamente scritto in C; ci deve essere almeno un po 'di linguaggio assembly (o qualsiasi altra cosa) che imposta un ambiente minimo in modo che una funzione C possa essere chiamata. Il nome più ovvio per quella funzione è main().
Dave Tweed

5

Un malinteso / mito comune è che int mainè l'unica forma valida specificata dallo standard. Quello non è vero.

Lo standard C parla di due implementazioni: ospitate e indipendenti. "Implementazione" in questo caso significa compilatore. Compilatori ospitati compilano per un sistema operativo specifico e compilatori indipendenti per una specifica applicazione bare metal. I sistemi integrati sono quasi sempre sistemi indipendenti, anche nel caso di RTOS.

Le implementazioni indipendenti possono utilizzare qualsiasi modulo per main(), non hanno nemmeno bisogno di avere una funzione chiamata main. Molto spesso, usano il modulo void main (void), poiché non ha senso restituire nulla.

Ciò che è importante capire qui è che è sempre il compilatore che decide la forma main()e mai il programmatore.

Freestanding implementazioni che fanno ritorno qualcosa main()sono molto discutibili. Ti fa chiedere se le persone che hanno creato il compilatore leggano effettivamente lo standard ...

Dettagli qui .


3

Lo standard del linguaggio C consente la variazione definita dall'implementazione void main( void )e questa è la solita forma nei sistemi embedded, semplicemente perché non si prevede che ritornino.

Se si guarda alla configurazione del compilatore, di solito c'è un frammento di codice bootstrap, chiamato dal vettore reset, che esegue alcune inizializzazioni di base (incluso ad esempio la copiatura dei valori di inizializzazione in variabili) prima di chiamare main ().

Anche questo (di solito) sarà all'interno di un ciclo infinito, o forse eseguirà un reset, se main()ritorna


0

(Come menzionato in altre risposte) dipende dalla tua toolchain, ma ad esempio in GCC mainviene compilato come altre funzioni, quindi il suo valore di ritorno verrà memorizzato conformemente alle convenzioni di chiamata (su ARM sto usando il diritto non con GCC verrà messo a R0 appena prima del ritorno).

Immagino che sia simile su AVR-GCC, quindi lo script personalizzato può usare questo valore dopo i ritorni principali.


questo alquanto manca il punto
Chris Stratton,

Sottolinea che chi chiama mainpuò ottenere il suo valore di ritorno. Naturalmente viene ignorato in situazioni del 99,9%, ma la risposta fornisce informazioni su chi può ricevere questo valore di ritorno.
kwesolowski,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.