Nunca escreva código assim.
Para j<1000
, j/1000
é zero (divisão inteira). Assim:
(&main + (&exit - &main)*(j/1000))(j+1);
é equivalente a:
(&main + (&exit - &main)*0)(j+1);
Qual é:
(&main)(j+1);
O que chama main
com j+1
.
Se j == 1000
, as mesmas linhas serão exibidas como:
(&main + (&exit - &main)*1)(j+1);
O que se resume a
(&exit)(j+1);
Qual é exit(j+1)
e sai do programa.
(&exit)(j+1)
e exit(j+1)
são essencialmente a mesma coisa - citando C99 §6.3.2.1 / 4:
Um designador de função é uma expressão que possui um tipo de função. Exceto quando é o operando do operador sizeof ou o operador unary & , um designador de função com o tipo " tipo de retorno de função " é convertido em uma expressão que possui o tipo " ponteiro para o tipo de retorno de função ".
exit
é um designador de função. Mesmo sem o operador de &
endereço unário , ele é tratado como um ponteiro para funcionar. (O &
just torna explícito.)
E as chamadas de função são descritas em §6.5.2.2 / 1 e seguintes:
A expressão que denota a função chamada deve ter ponteiro de tipo para retornar nulo ou retornar um tipo de objeto diferente de um tipo de matriz.
Assim, exit(j+1)
funciona devido à conversão automática do tipo de função em um tipo de ponteiro para função e também (&exit)(j+1)
funciona com uma conversão explícita em um tipo de ponteiro para função.
Dito isto, o código acima não está em conformidade ( main
aceita dois argumentos ou nenhum) e &exit - &main
, acredito, é indefinido de acordo com §6.5.6 / 9:
Quando dois ponteiros são subtraídos, ambos apontam para elementos do mesmo objeto de matriz ou um após o último elemento do objeto de matriz; ...
A adição (&main + ...)
seria válida por si só e poderia ser utilizada se a quantidade adicionada fosse zero, uma vez que o §6.5.6 / 7 diz:
Para os fins desses operadores, um ponteiro para um objeto que não é um elemento de uma matriz se comporta da mesma forma que um ponteiro para o primeiro elemento de uma matriz de comprimento um com o tipo de objeto como seu tipo de elemento.
Portanto, adicionar zero a &main
seria aceitável (mas não muito útil).
main
em C ++.