Non scrivere mai codice del genere.
Per j<1000
, j/1000
è zero (divisione intera). Così:
(&main + (&exit - &main)*(j/1000))(j+1);
è equivalente a:
(&main + (&exit - &main)*0)(j+1);
Che è:
(&main)(j+1);
Che chiama main
con j+1
.
Se j == 1000
, allora vengono fuori le stesse linee di:
(&main + (&exit - &main)*1)(j+1);
Il che si riduce a
(&exit)(j+1);
Che è exit(j+1)
e lascia il programma.
(&exit)(j+1)
e exit(j+1)
sono essenzialmente la stessa cosa - citando C99 §6.3.2.1 / 4:
Un designatore di funzioni è un'espressione con tipo di funzione. Tranne quando si tratta dell'operando dell'operatore sizeof o dell'operatore unario e , un designatore di funzione con tipo " tipo di ritorno di funzione " viene convertito in un'espressione che ha il tipo " puntatore a tipo di ritorno di funzione ".
exit
è un designatore di funzioni. Anche senza l'operatore unario di &
indirizzo, viene trattato come un puntatore alla funzione. (Il &
giusto lo rende esplicito.)
E le chiamate di funzione sono descritte in §6.5.2.2 / 1 e seguenti:
L'espressione che indica la funzione chiamata deve avere un puntatore di tipo per la funzione che restituisce il vuoto o restituisce un tipo di oggetto diverso da un tipo di matrice.
Quindi exit(j+1)
funziona a causa della conversione automatica del tipo di funzione in un tipo puntatore a funzione e (&exit)(j+1)
funziona anche con una conversione esplicita in un tipo puntatore a funzione.
Detto questo, il codice sopra riportato non è conforme ( main
accetta due argomenti o nessuno), ed &exit - &main
è, a mio avviso, indefinito in base al § 6.5.5 / 9:
Quando vengono sottratti due puntatori, entrambi devono puntare a elementi dello stesso oggetto array o uno oltre l'ultimo elemento dell'oggetto array; ...
L'aggiunta (&main + ...)
sarebbe valida di per sé e potrebbe essere utilizzata se la quantità aggiunta fosse zero, poiché §6.5.6 / 7 dice:
Ai fini di questi operatori, un puntatore a un oggetto che non è un elemento di un array si comporta come un puntatore al primo elemento di un array di lunghezza uno con il tipo di oggetto come tipo di elemento.
Quindi aggiungere zero a &main
sarebbe ok (ma non molto uso).
main
in C ++.