Standar C - Lingkungan yang Diinangi
Untuk lingkungan yang dihosting (itu yang normal), standar C11 (ISO / IEC 9899: 2011) mengatakan:
5.1.2.2.1 Startup program
Fungsi yang dipanggil saat startup program dinamai main. Implementasi menyatakan tidak ada prototipe untuk fungsi ini. Ini harus didefinisikan dengan tipe pengembalian intdan tanpa parameter:
int main(void) { /* ... */ }
atau dengan dua parameter (disebut di sini sebagai argcdan argv, meskipun nama apa pun dapat digunakan, karena mereka lokal untuk fungsi di mana mereka dinyatakan):
int main(int argc, char *argv[]) { /* ... */ }
atau setara; 10) atau dengan cara lain yang ditentukan implementasi.
Jika dinyatakan, parameter ke fungsi utama harus mematuhi batasan berikut:
- Nilai
argcharus tidak negatif.
argv[argc] akan menjadi pointer nol.
- Jika nilai
argclebih besar dari nol, anggota array argv[0]melalui
argv[argc-1]inklusif harus berisi pointer ke string, yang diberi nilai-nilai implementasi-didefinisikan oleh lingkungan host sebelum startup program. Maksudnya adalah untuk menyediakan informasi program yang ditentukan sebelum memulai program dari tempat lain di lingkungan yang dihosting. Jika lingkungan host tidak mampu menyediakan string dengan huruf besar dan kecil, implementasi harus memastikan bahwa string diterima dalam huruf kecil.
- Jika nilai
argclebih besar dari nol, string yang ditunjuk oleh argv[0]
mewakili nama program; argv[0][0]akan menjadi karakter nol jika nama program tidak tersedia dari lingkungan host. Jika nilai argclebih besar dari satu, string yang ditunjuk oleh argv[1]melalui argv[argc-1]
mewakili parameter Program.
- Parameter
argcdan argvdan string yang ditunjukkan oleh argvarray harus dapat dimodifikasi oleh program, dan mempertahankan nilai-nilai yang terakhir disimpan antara startup dan penghentian program.
10) Dengan demikian, intdapat diganti dengan nama typedef didefinisikan sebagai int, atau jenis argvdapat ditulis sebagai
char **argv, dan seterusnya.
Pengakhiran program dalam C99 atau C11
Nilai yang dikembalikan dari main()ditransmisikan ke 'lingkungan' dengan cara yang ditentukan implementasi.
5.1.2.2.3 Pengakhiran program
1 Jika tipe pengembalian mainfungsi adalah tipe yang kompatibel dengan int, pengembalian dari panggilan awal ke mainfungsi setara dengan memanggil exitfungsi dengan nilai yang dikembalikan oleh mainfungsi sebagai argumennya; 11) mencapai }yang mengakhiri
mainfungsi mengembalikan nilai 0. Jika jenis kembali tidak kompatibel dengan int, status penghentian kembali ke lingkungan host tidak ditentukan.
11) Sesuai dengan 6.2.4, masa hidup objek dengan durasi penyimpanan otomatis yang dinyatakan dalam main
akan berakhir pada kasus sebelumnya, bahkan di mana mereka tidak akan memiliki dalam yang terakhir.
Catatan yang 0diamanatkan sebagai 'sukses'. Anda dapat menggunakan EXIT_FAILUREdan EXIT_SUCCESSdari <stdlib.h>jika Anda mau, tetapi 0 sudah mapan, dan begitu juga 1. Lihat juga kode Keluar lebih besar dari 255 - mungkin? .
Di C89 (dan karenanya di Microsoft C), tidak ada pernyataan tentang apa yang terjadi jika main()fungsi kembali tetapi tidak menentukan nilai kembali; oleh karena itu mengarah pada perilaku yang tidak terdefinisi.
7.22.4.4 exitFungsi
¶5 Akhirnya, kontrol dikembalikan ke lingkungan host. Jika nilai statusnol atau EXIT_SUCCESS, bentuk yang ditentukan implementasi status pemutusan berhasil dikembalikan. Jika nilainya statusadalah EXIT_FAILURE, bentuk pemutusan status yang ditentukan implementasi tidak dikembalikan. Kalau tidak, status yang dikembalikan ditentukan oleh implementasi.
Standar C ++ - Lingkungan yang Diinangi
Standar C ++ 11 (ISO / IEC 14882: 2011) mengatakan:
3.6.1 Fungsi utama [basic.start.main]
¶1 Suatu program harus mengandung fungsi global yang disebut main, yang merupakan awal dari program yang ditunjuk. [...]
¶2 Suatu implementasi tidak akan menentukan fungsi utama. Fungsi ini tidak akan kelebihan beban. Ini harus memiliki tipe pengembalian tipe int, tetapi jika tidak jenisnya implementasi didefinisikan. Semua implementasi harus memungkinkan kedua definisi utama berikut:
int main() { /* ... */ }
dan
int main(int argc, char* argv[]) { /* ... */ }
Dalam bentuk yang terakhir argcharus ada sejumlah argumen yang diteruskan ke program dari lingkungan di mana program dijalankan. Jika argcbukan nol, argumen ini harus disertakan argv[0]
melalui argv[argc-1]sebagai penunjuk ke karakter awal string multibyte yang diakhiri null (NTMBS) (17.5.2.1.4.2) dan argv[0]harus menjadi penunjuk ke karakter awal NTMBS yang mewakili nama yang digunakan untuk aktifkan program atau "". Nilai argcharus tidak negatif. Nilai argv[argc]
harus 0. [Catatan: Disarankan agar parameter lebih lanjut (opsional) ditambahkan setelahnya argv. —Kirim catatan]
¶3 Fungsi maintidak akan digunakan dalam suatu program. Linkage (3.5) dari maindidefinisikan oleh implementasi. [...]
¶5 Pernyataan kembali pada main memiliki efek meninggalkan fungsi utama (menghancurkan objek dengan durasi penyimpanan otomatis) dan memanggil std::exitdengan nilai kembali sebagai argumen. Jika kontrol mencapai ujung main tanpa menemui pernyataan pengembalian, efeknya adalah menjalankan
return 0;
Standar C ++ secara eksplisit mengatakan "Ini [fungsi utama] harus memiliki tipe tipe pengembalian int, tetapi jika tidak tipe implementasinya didefinisikan", dan memerlukan dua tanda tangan yang sama dengan standar C yang akan didukung sebagai opsi. Jadi 'void main ()' secara langsung tidak diizinkan oleh standar C ++, meskipun tidak ada yang bisa dilakukan untuk menghentikan implementasi non-standar yang memungkinkan alternatif. Perhatikan bahwa C ++ melarang pengguna menelepon main(tetapi standar C tidak).
Ada sebuah paragraf dari §18.5 Start dan terminasi di C ++ 11 standar yang identik dengan paragraf dari §7.22.4.4 The exitfungsi dalam standar C11 (dikutip di atas), terpisah dari catatan kaki (yang hanya dokumen yang EXIT_SUCCESSdan EXIT_FAILUREdidefinisikan dalam <cstdlib>).
Standar C - Ekstensi Umum
Secara klasik, sistem Unix mendukung varian ketiga:
int main(int argc, char **argv, char **envp) { ... }
Argumen ketiga adalah daftar null yang diakhiri dari pointer ke string, yang masing-masing merupakan variabel lingkungan yang memiliki nama, tanda sama dengan, dan nilai (mungkin kosong). Jika Anda tidak menggunakan ini, Anda masih bisa masuk ke lingkungan melalui ' extern char **environ;'. Variabel global ini unik di antara mereka yang ada di POSIX karena tidak memiliki header yang menyatakannya.
Ini diakui oleh standar C sebagai perpanjangan umum, yang didokumentasikan dalam Lampiran J:
J.5.1 Argumen lingkungan
¶1 Dalam lingkungan yang dihosting, fungsi utama menerima argumen ketiga char *envp[],, yang menunjuk ke array pointer yang diakhiri dengan null char, masing-masing menunjuk ke string yang memberikan informasi tentang lingkungan untuk pelaksanaan program ini (5.1. 2.2.1).
Microsoft C
The Microsoft VS 2010 compiler menarik. Situs web mengatakan:
Sintaks deklarasi untuk main adalah
int main();
atau, secara opsional,
int main(int argc, char *argv[], char *envp[]);
Atau, fungsi maindan wmaindapat dinyatakan sebagai kembali void(tidak ada nilai balik). Jika Anda menyatakan mainatau wmainsebagai batal kembali, Anda tidak dapat mengembalikan kode keluar ke proses induk atau sistem operasi dengan menggunakan pernyataan kembali. Untuk mengembalikan kode keluar saat mainatau wmaindinyatakan sebagai void, Anda harus menggunakan exitfungsi ini.
Tidak jelas bagi saya apa yang terjadi (kode keluar apa yang dikembalikan ke induk atau OS) ketika program dengan void main()apakah keluar - dan situs web MS juga diam.
Menariknya, MS tidak meresepkan versi dua argumen main()yang dibutuhkan oleh standar C dan C ++. Ini hanya menentukan bentuk argumen tiga di mana argumen ketiga adalah char **envp, pointer ke daftar variabel lingkungan.
Halaman Microsoft juga mencantumkan beberapa alternatif lain - wmain()yang mengambil string karakter lebar, dan beberapa lagi.
Microsoft Visual Studio 2005 versi halaman ini tidak daftar void main()sebagai alternatif. The versi dari Microsoft Visual Studio 2008 dan seterusnya lakukan.
Standar C - Lingkungan Berdiri Bebas
Seperti disebutkan sebelumnya, persyaratan di atas berlaku untuk lingkungan yang dihosting. Jika Anda bekerja dengan lingkungan yang berdiri sendiri (yang merupakan alternatif untuk lingkungan yang dihosting), maka standar memiliki lebih sedikit untuk dikatakan. Untuk lingkungan yang berdiri sendiri, fungsi yang dipanggil saat startup program tidak perlu dipanggil maindan tidak ada batasan pada tipe pengembaliannya. Standar mengatakan:
5.1.2 Lingkungan eksekusi
Dua lingkungan eksekusi didefinisikan: berdiri bebas dan dihosting. Dalam kedua kasus, startup program terjadi ketika fungsi C yang ditunjuk dipanggil oleh lingkungan eksekusi. Semua objek dengan durasi penyimpanan statis harus diinisialisasi (diatur ke nilai awal) sebelum memulai program. Cara dan waktu inisialisasi tersebut tidak ditentukan. Pengakhiran program mengembalikan kontrol ke lingkungan eksekusi.
5.1.2.1 Lingkungan berdiri bebas
Dalam lingkungan yang berdiri sendiri (di mana eksekusi program C dapat terjadi tanpa manfaat dari sistem operasi), nama dan jenis fungsi yang dipanggil saat startup program ditentukan oleh implementasi. Fasilitas perpustakaan apa pun yang tersedia untuk program berdiri bebas, selain dari set minimal yang disyaratkan oleh klausul 4, ditentukan oleh implementasi.
Efek penghentian program dalam lingkungan yang berdiri sendiri ditentukan oleh implementasi.
Referensi silang ke ayat 4 Kesesuaian mengacu pada ini:
¶5 Program yang sangat sesuai hanya akan menggunakan fitur-fitur bahasa dan perpustakaan yang ditentukan dalam Standar Internasional ini. 3) Ini tidak akan menghasilkan output tergantung pada perilaku yang tidak ditentukan, tidak ditentukan, atau ditentukan implementasi, dan tidak boleh melebihi batas implementasi minimum.
¶6 Dua bentuk implementasi yang sesuai dihosting dan berdiri bebas . Sebuah implementasi host sesuai akan menerima program secara ketat sesuai. Sebuah implementasi berdiri bebas sesuai akan menerima program secara ketat sesuai di mana penggunaan fitur-fitur tertentu dalam klausa perpustakaan (klausul 7) hanya terbatas pada isi dari header standar <float.h>, <iso646.h>, <limits.h>, <stdalign.h>,
<stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, dan
<stdnoreturn.h>. Implementasi yang sesuai mungkin memiliki ekstensi (termasuk fungsi pustaka tambahan), asalkan mereka tidak mengubah perilaku program yang benar-benar sesuai. 4)
¶7 Program yang sesuai adalah yang dapat diterima untuk implementasi yang sesuai. 5)
3) Program yang benar-benar sesuai dapat menggunakan fitur bersyarat (lihat 6.10.8.3) asalkan penggunaannya dijaga oleh arahan preprocessing inklusi bersyarat yang sesuai menggunakan makro terkait. Sebagai contoh:
#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
/* ... */
fesetround(FE_UPWARD);
/* ... */
#endif
4) Ini menyiratkan bahwa implementasi yang sesuai cadangan tidak ada pengidentifikasi selain yang secara eksplisit dicadangkan dalam Standar Internasional ini.
5) Program yang benar-benar sesuai dimaksudkan agar portabel secara maksimal di antara implementasi yang sesuai. Program yang sesuai mungkin tergantung pada fitur non-portabel dari implementasi yang sesuai.
Terlihat bahwa satu-satunya header yang diperlukan untuk lingkungan yang berdiri sendiri yang benar-benar mendefinisikan fungsi apa pun adalah <stdarg.h>(dan bahkan yang mungkin - dan seringkali - hanya makro).
Standar C ++ - Lingkungan Berdiri Bebas
Sama seperti standar C yang mengenali lingkungan yang di-host dan berdiri bebas, demikian juga standar C ++. (Kutipan dari ISO / IEC 14882: 2011.)
1.4 Kepatuhan implementasi [intro.compliance]
¶7 Dua jenis implementasi didefinisikan: implementasi yang di-host dan implementasi yang berdiri sendiri . Untuk implementasi yang dihosting, Standar Internasional ini mendefinisikan set perpustakaan yang tersedia. Implementasi berdiri bebas adalah implementasi di mana eksekusi dapat berlangsung tanpa manfaat dari sistem operasi, dan memiliki seperangkat perpustakaan yang didefinisikan implementasi yang mencakup perpustakaan dukungan bahasa tertentu (17.6.1.3).
¶8 Implementasi yang sesuai mungkin memiliki ekstensi (termasuk fungsi perpustakaan tambahan), asalkan mereka tidak mengubah perilaku dari setiap program yang dibentuk dengan baik. Implementasi diperlukan untuk mendiagnosis program yang menggunakan ekstensi tersebut yang bentuknya tidak sesuai dengan Standar Internasional ini. Namun, setelah melakukannya, mereka dapat menyusun dan menjalankan program-program tersebut.
Each9 Setiap implementasi harus menyertakan dokumentasi yang mengidentifikasi semua konstruksi yang didukung kondisional yang tidak mendukung dan mendefinisikan semua karakteristik khusus lokal. 3
3) Dokumentasi ini juga mendefinisikan perilaku yang ditentukan implementasi; lihat 1.9.
17.6.1.3 Implementasi berdiri bebas [kepatuhan]
Dua jenis implementasi didefinisikan: di-host dan berdiri bebas (1.4). Untuk implementasi yang dihosting, Standar Internasional ini menjelaskan kumpulan tajuk yang tersedia.
Implementasi berdiri bebas memiliki set header yang ditentukan implementasi. Set ini harus mencakup setidaknya header yang ditunjukkan pada Tabel 16.
Versi disediakan dari header <cstdlib>wajib menyatakan setidaknya fungsi abort, atexit, at_quick_exit, exit, dan quick_exit(18,5). Header lain yang tercantum dalam tabel ini harus memenuhi persyaratan yang sama seperti untuk implementasi yang di-host.
Tabel 16 - header C ++ untuk implementasi freestanding
Subclause Header(s)
<ciso646>
18.2 Types <cstddef>
18.3 Implementation properties <cfloat> <limits> <climits>
18.4 Integer types <cstdint>
18.5 Start and termination <cstdlib>
18.6 Dynamic memory management <new>
18.7 Type identification <typeinfo>
18.8 Exception handling <exception>
18.9 Initializer lists <initializer_list>
18.10 Other runtime support <cstdalign> <cstdarg> <cstdbool>
20.9 Type traits <type_traits>
29 Atomics <atomic>
Bagaimana dengan menggunakan int main()di C?
Standar §5.1.2.2.1 dari standar C11 menunjukkan notasi yang disukai - int main(void)- tetapi ada juga dua contoh dalam standar yang menunjukkan int main(): §6.5.3.4 ¶8 dan §6.7.6.3 ¶20 . Sekarang, penting untuk dicatat bahwa contoh tidak 'normatif'; mereka hanya ilustratif. Jika ada bug dalam contoh, mereka tidak secara langsung mempengaruhi teks utama standar. Yang mengatakan, mereka sangat menunjukkan perilaku yang diharapkan, jadi jika standar termasuk int main()dalam contoh, itu menunjukkan bahwa int main()tidak dilarang, bahkan jika itu bukan notasi yang disukai.
6.5.3.4 The sizeofdan _Alignofoperator
...
¶8 CONTOH 3 Dalam contoh ini, ukuran array panjang variabel dihitung dan dikembalikan dari suatu fungsi:
#include <stddef.h>
size_t fsize3(int n)
{
char b[n+3]; // variable length array
return sizeof b; // execution time sizeof
}
int main()
{
size_t size;
size = fsize3(10); // fsize3 returns 13
return 0;
}