Saya baru saja membaca
ISO / IEC 9899: 201x Panitia Draft - 12 April 2011
di mana saya temukan di bawah 5.1.2.2.3 Penghentian program
..reaching the } that terminates the main function returns a value of 0.
ini berarti jika Anda tidak menentukan pernyataan pengembalian apa pun di main()
, dan jika program berjalan dengan sukses, maka pada tanda kurung kurawal} dari main akan mengembalikan 0.
Tetapi dalam kode berikut saya tidak menentukan pernyataan pengembalian apa pun, namun tidak mengembalikan 0
#include<stdio.h>
int sum(int a,int b)
{
return (a + b);
}
int main()
{
int a=10;
int b=5;
int ans;
ans=sum(a,b);
printf("sum is %d",ans);
}
menyusun
gcc test.c
./a.out
sum is 15
echo $?
9 // here it should be 0 but it shows 9 why?
gcc
dengan sendirinya (untuk versi 4.6.2) mengkompilasi bahasa yang sangat mirip tetapi tidak persis seperti C. Ia mengkompilasi GnuC89 - bahasa "secara longgar" berdasarkan C89.return
pernyataan disum()
tidak perlu.int main()
seharusnyaint main(void)
.Jawaban:
Aturan itu ditambahkan pada standar C versi 1999. Di C90, status yang dikembalikan tidak ditentukan.
Anda dapat mengaktifkannya dengan meneruskan
-std=c99
ke gcc.Sebagai catatan tambahan, menariknya 9 dikembalikan karena memang pengembaliannya
printf
baru aja 9 karakter.sumber
return 0;
sebelum penutupan}
. Tidak berbahaya dan membuat program Anda portabel untuk kompiler yang lebih tua.eax
khususnya pada x86.eax
register. Lihat en.wikipedia.org/wiki/X86_calling_conventions#cdecl untuk informasi lebih lanjut.Ia mengembalikan nilai
printf
yang merupakan jumlah karakter yang benar-benar dicetak.sumber
%errorlevel%
di Windows, apakah ada perbedaan antara kode keluar dan nilai pengembalianmain
di linux?printf
yang dalam hal ini adalah 9 yang kemudian akan "dipromosikan" sebagai kode keluar darimain
entah bagaimana bila menggunakan versi gcc tertentu.Nilai kembali dari suatu fungsi biasanya disimpan dalam register eax dari cpu, jadi pernyataan "return 4;" biasanya akan dikompilasi menjadi
dan kembalikan x (tergantung pada kompiler Anda) akan menjadi seperti ini:
jika Anda tidak menentukan nilai yang dikembalikan maka kompilator akan tetap mengeluarkan "ret" tetapi tidak mengubah nilai eax. Jadi pemanggil akan berpikir bahwa apa yang tersisa di register eax sebelumnya adalah nilai kembali. Untuk contoh ini biasanya akan menjadi nilai kembali printf, tetapi kompiler yang berbeda akan menghasilkan kode mesin yang berbeda dan menggunakan beberapa register secara berbeda.
Ini adalah penjelasan yang disederhanakan, konvensi panggilan yang berbeda dan platform target akan memainkan peran penting, tetapi informasi tersebut harus cukup untuk menjelaskan apa yang terjadi 'di balik layar' dalam contoh Anda.
Jika Anda memiliki pemahaman dasar tentang assembler, ada baiknya membandingkan pembongkaran berbagai kompiler. Anda mungkin menemukan bahwa beberapa kompiler membersihkan register eax sebagai pengaman.
sumber