Nigdy nie pisz takiego kodu.
Dla j<1000
, j/1000
wynosi zero (dzielenie liczb całkowitych). Więc:
(&main + (&exit - &main)*(j/1000))(j+1);
jest równa:
(&main + (&exit - &main)*0)(j+1);
Który jest:
(&main)(j+1);
Który nazywa main
się j+1
.
Jeśli j == 1000
, to te same linie wychodzą jako:
(&main + (&exit - &main)*1)(j+1);
Co sprowadza się do
(&exit)(j+1);
Który jest exit(j+1)
i opuszcza program.
(&exit)(j+1)
i exit(j+1)
zasadniczo są tym samym - cytując C99 §6.3.2.1 / 4:
Desygnator funkcji to wyrażenie, które ma typ funkcji. Z wyjątkiem sytuacji, gdy jest to operand operatora sizeof lub jednoargumentowy & operator , desygnator funkcji z typem „ funkcja zwracająca typ ” jest konwertowany na wyrażenie, które ma typ „ wskaźnik do funkcji zwracającej typ ”.
exit
jest wyznacznikiem funkcji. Nawet bez jednoargumentowego &
operatora address-of jest traktowany jako wskaźnik do funkcji. (Po &
prostu to wyjaśnia).
Wywołania funkcji opisano w §6.5.2.2 / 1 i poniżej:
Wyrażenie, które oznacza wywoływaną funkcję, powinno mieć wskaźnik typu do funkcji zwracającej void lub zwracającej typ obiektu inny niż typ tablicowy.
exit(j+1)
Działa więc z powodu automatycznej konwersji typu funkcji na typ wskaźnika do funkcji i (&exit)(j+1)
działa również z jawną konwersją na typ wskaźnika do funkcji.
To powiedziawszy, powyższy kod nie jest zgodny ( main
przyjmuje dwa argumenty lub wcale) i &exit - &main
jest, jak sądzę, niezdefiniowany zgodnie z §6.5.6 / 9:
Gdy odejmowane są dwa wskaźniki, oba wskazują elementy tego samego obiektu tablicy lub jeden za ostatnim elementem obiektu tablicy; ...
Dodatek (&main + ...)
byłby ważny sam w sobie i mógłby zostać użyty, gdyby dodana ilość wynosiła zero, ponieważ §6.5.6 / 7 mówi:
Na potrzeby tych operatorów wskaźnik do obiektu, który nie jest elementem tablicy, zachowuje się tak samo, jak wskaźnik do pierwszego elementu tablicy o długości jeden z typem obiektu jako typem elementu.
Więc dodanie zera do &main
byłoby w porządku (ale nie jest zbyt przydatne).
main
w C ++.