Siapa yang menerima nilai yang dikembalikan oleh main ()?

34

Saya tahu bahwa di komputer, nilai yang dikembalikan oleh main()fungsi diterima oleh sistem operasi. Tapi, apa yang terjadi pada main()fungsi mikrokontroler?

pengguna18118
sumber
7
Saya selalu menggunakan void main () ketika saya menggunakan C untuk PIC mikrokontroler. Saat menggunakan kompiler C untuk mikrokontroler, itu benar-benar tidak masalah sama sekali. Karena tidak ada sistem operasi yang menjalankan (katakanlah) "main.c". Jika ada sesuatu seperti RTOS yang berjalan di mikrokontroler itu, maka sistem operasinya adalah "main.c".
abdullah kahraman
4
Tidak benar-benar duplikat, tetapi setidaknya terkait: electronics.stackexchange.com/q/30830/4950
PetPaulsen
1
Bagaimana fungsi startup didefinisikan biasanya tidak terserah Anda untuk memutuskan. Lingkungan yang Anda gunakan akan mendokumentasikan formulir fungsi startup yang didukung. Implementasi Hosted C diperlukan untuk mendukung dua bentuk maindengan dua tanda tangan yang berbeda, yang keduanya kembali int. Jika Anda menggunakan implementasi C berdiri bebas, implementasi itu menentukan bagaimana Anda harus menulis fungsi startup. Anda tidak dapat menulis voidfungsi kembali hanya karena tidak kembali. The perilaku dari tidak kembali berbeda dari fungsi jenis yang mempengaruhi konvensi panggilan secara keseluruhan.
Kaz

Jawaban:

42

Pada mikrokontroler, main()tidak benar-benar diharapkan untuk keluar, dan perilaku jika tidak didefinisikan - jadi terserah siapa pun yang menulis runtime C untuk mikrokontroler. Saya telah melihat sistem yang:

  • Memiliki loop implisit di sekitar main(), sehingga jika keluar, itu akan dipanggil lagi.
  • Miliki loop "lompat-ke-diri" sederhana yang dijalankan jika main()pernah keluar.
  • Cukup jalankan sisa memori kode yang mengikuti panggilan ke main(). Ini disebut "mengalir ke gulma".

Saya belum pernah melihat satu yang benar-benar melakukan apa pun dengan nilai yang dikembalikan main(). Jika ini adalah sesuatu yang benar-benar Anda pedulikan, maka Anda harus melihat - dan mungkin memodifikasi - kode sumber untuk pustaka runtime C sistem Anda.

Dave Tweed
sumber
1
Anda mengalahkan saya untuk itu. +1 untuk sinkronisasi.
Adam Lawrence
9
Standar C yang mendefinisikan main()memiliki intnilai kembali jelas tidak dirancang dengan mikrokontroler OS-kurang dalam pikiran. Jadi ini adalah perilaku yang tidak ditentukan dan apa pun dapat terjadi tergantung pada runtime C Anda, seperti yang tercantum dalam daftar.
ndim
4
C berjalan pada mikrokontroler OS-kurang bisa dianggap sebagai implementasi berdiri bebas, dan C standar bahkan tidak memerlukan environent berdiri bebas untuk memiliki sebuah main(), apalagi menentukan nilai kembali. Terserah implementor.
KutuluMike
2
@ndim - untuk memisahkan rambut, void main( void )adalah implementasi perilaku yang ditentukan , bukan perilaku yang tidak ditentukan .
Andrew
1
@MichaelEdenfield: Memang. Namun, semua kode dalam C didefinisikan dari segi fungsi, sehingga tidak mungkin untuk memiliki sistem fresstanding yang sepenuhnya ditulis dalam C; harus ada setidaknya sedikit bahasa assembly (atau apa pun) yang mengatur lingkungan minimal sehingga fungsi C dapat dipanggil. Nama yang paling jelas untuk fungsi itu adalah main().
Dave Tweed
5

Kesalahpahaman / mitos yang umum adalah itu int mainadalah satu-satunya bentuk valid yang ditentukan oleh standar. Itu tidak benar.

Standar C berbicara tentang dua implementasi: di-host dan berdiri bebas. "Implementasi" dalam hal ini berarti kompiler. Compiler yang dihosting mengkompilasi untuk OS tertentu dan kompiler yang berdiri bebas mengkompilasi untuk aplikasi bare metal tertentu. Sistem tertanam hampir selalu merupakan sistem yang berdiri sendiri - bahkan dalam kasus RTOS.

Implementasi berdiri bebas dapat menggunakan formulir apa pun untuk main(), mereka bahkan tidak perlu memiliki fungsi yang disebut main. Paling sering, mereka menggunakan formulir void main (void), karena tidak masuk akal untuk mengembalikan apa pun.

Apa yang penting untuk disadari di sini adalah bahwa selalu kompiler yang memutuskan bentuk main()dan tidak pernah programmer.

Berdiri bebas implementasi yang melakukan kembali sesuatu darimain() yang sangat dipertanyakan. Membuat Anda bertanya-tanya apakah orang-orang yang membuat kompiler benar-benar membaca standar ...

Detail di sini .

Lundin
sumber
3

Standar bahasa C memungkinkan untuk variasi implementasi yang ditentukan void main( void )dan ini adalah bentuk yang biasa dalam sistem embedded - hanya karena mereka tidak diharapkan untuk kembali.

Jika Anda melihat pengaturan kompiler, biasanya ada potongan kode bootstrap, dipanggil dari vektor reset, yang melakukan beberapa inisialisasi dasar (termasuk misalnya mengatasi nilai inisialisasi ke dalam variabel) sebelum memanggil main ().

Ini juga akan (biasanya) berada dalam loop tak terbatas, atau mungkin melakukan reset, jika main()kembali

Andrew
sumber
0

Itu (seperti jawaban lain yang disebutkan) tergantung pada toolchain Anda, tetapi misalnya dalam GCC maindikompilasi sebagai fungsi lain, sehingga nilai pengembaliannya akan disimpan sesuai dengan konvensi pemanggilan (pada ARM saya menggunakan benar bukan dengan GCC itu akan dimasukkan ke R0 sesaat sebelum kembali).

Saya kira itu adalah simillar pada AVR-GCC, jadi skrip khusus dapat menggunakan nilai ini setelah pengembalian utama.

kwesolowski
sumber
ini agak merindukan intinya
Chris Stratton
Ini menekankan bahwa orang yang menelepon mainbisa mendapatkan nilai baliknya. Tentu saja diabaikan dalam situasi 99,9%, tetapi jawaban memberikan informasi siapa yang dapat menerima nilai pengembalian ini.
kwesolowski