Nigdy nie pisz takiego kodu.
Dla j<1000, j/1000wynosi 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 mainsię 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 ”.
exitjest 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 ( mainprzyjmuje dwa argumenty lub wcale) i &exit - &mainjest, 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 &mainbyłoby w porządku (ale nie jest zbyt przydatne).
mainw C ++.