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 int
dan tanpa parameter:
int main(void) { /* ... */ }
atau dengan dua parameter (disebut di sini sebagai argc
dan 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
argc
harus tidak negatif.
argv[argc]
akan menjadi pointer nol.
- Jika nilai
argc
lebih 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
argc
lebih 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 argc
lebih besar dari satu, string yang ditunjuk oleh argv[1]
melalui argv[argc-1]
mewakili parameter Program.
- Parameter
argc
dan argv
dan string yang ditunjukkan oleh argv
array harus dapat dimodifikasi oleh program, dan mempertahankan nilai-nilai yang terakhir disimpan antara startup dan penghentian program.
10) Dengan demikian, int
dapat diganti dengan nama typedef didefinisikan sebagai int
, atau jenis argv
dapat 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 main
fungsi adalah tipe yang kompatibel dengan int
, pengembalian dari panggilan awal ke main
fungsi setara dengan memanggil exit
fungsi dengan nilai yang dikembalikan oleh main
fungsi sebagai argumennya; 11) mencapai }
yang mengakhiri
main
fungsi 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 0
diamanatkan sebagai 'sukses'. Anda dapat menggunakan EXIT_FAILURE
dan EXIT_SUCCESS
dari <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 exit
Fungsi
¶5 Akhirnya, kontrol dikembalikan ke lingkungan host. Jika nilai status
nol atau EXIT_SUCCESS
, bentuk yang ditentukan implementasi status pemutusan berhasil dikembalikan. Jika nilainya status
adalah 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 argc
harus ada sejumlah argumen yang diteruskan ke program dari lingkungan di mana program dijalankan. Jika argc
bukan 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 argc
harus tidak negatif. Nilai argv[argc]
harus 0. [Catatan: Disarankan agar parameter lebih lanjut (opsional) ditambahkan setelahnya argv
. —Kirim catatan]
¶3 Fungsi main
tidak akan digunakan dalam suatu program. Linkage (3.5) dari main
didefinisikan oleh implementasi. [...]
¶5 Pernyataan kembali pada main memiliki efek meninggalkan fungsi utama (menghancurkan objek dengan durasi penyimpanan otomatis) dan memanggil std::exit
dengan 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 exit
fungsi dalam standar C11 (dikutip di atas), terpisah dari catatan kaki (yang hanya dokumen yang EXIT_SUCCESS
dan EXIT_FAILURE
didefinisikan 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 main
dan wmain
dapat dinyatakan sebagai kembali void
(tidak ada nilai balik). Jika Anda menyatakan main
atau wmain
sebagai batal kembali, Anda tidak dapat mengembalikan kode keluar ke proses induk atau sistem operasi dengan menggunakan pernyataan kembali. Untuk mengembalikan kode keluar saat main
atau wmain
dinyatakan sebagai void
, Anda harus menggunakan exit
fungsi 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 main
dan 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 sizeof
dan _Alignof
operator
...
¶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;
}