Odpovídám proto, že všechny existující odpovědi říkají, že jde o nedefinované chování, což není pravda, takže nemám nic, co bych mohl hlasovat.
V C89 (díky pmg za odkaz na návrh normy), 5.1.2.2.3:
Návrat z počátečního volání funkce main je ekvivalentní volání funkce exit s hodnotou vrácenou funkcí main jako jejím argumentem. Pokud je dosaženo hodnoty, která ukončuje hlavní funkci, stav ukončení vrácený hostitelskému prostředí není specifikován.
V C99, cituji z n1256, 5.1.2.2.3:
Je-li návratovým typem hlavní funkce typ kompatibilní uvnitř, návrat z počátečního volání hlavní funkce je ekvivalentní volání výstupní funkce s hodnotou vrácenou argumentem hlavní funkce asts; dosažení }, které ukončuje hlavní funkci, vrátí hodnotu 0. Pokud návratový typ není kompatibilní s int, není koncový stav vrácený hostitelskému prostředí specifikován.
Nejde tedy o "nedefinované chování":chová se, jako by main
funkce vrací, ale v C89 vrácená hodnota není specifikována standardem. Pro váš vzorový program se při vaší implementaci zdá, že vrácená hodnota je konzistentně 12, pravděpodobně z důvodu, jak říká Ben Voigt. Vzhledem k tomu, že používáte linux, pravděpodobně není velkou změnou kompilovat váš kód jako C99 (nebo jej zkompilovat pomocí téměř kompatibilního režimu C99 v gcc).
Pro jakoukoli funkci, která vrací hodnotu jinou než main
, to je nedefinované chování, pokud volající nepoužívá návratovou hodnotu (n1256, 6.9.1/12):
Pokud je dosaženo }, které ukončuje funkci, a volající použije hodnotu functioncall, chování není definováno.
Nejsem si jistý, zda počáteční volání main
by měly být uvedeny jako vyloučené z tohoto obecného pravidla. Nemusí to být:z POV standardu tento hovor nemá volajícího, takže si myslím, že hodnota volání funkce není "použita volajícím", i když se stává stavem ukončení pro program.
Jak říká swegi, je to nedefinované chování. Jak říká Steve Jessop et al, je to nespecifikovaná hodnota až do C89 a specifikovaná v C99 (pozorované chování není v souladu s C99)
Ve většině prostředí se ve skutečnosti stane návratová hodnota z posledního printf
je ponecháno v registru používaném pro návratové hodnoty.
Bude to tedy 11 pro n ==0, 12, pokud je n jednociferné, 14 pro dvouciferné n, 16 pro tříciferné n atd.