Nunca escribas código como ese.
Para j<1000
, j/1000
es cero (división entera). Entonces:
(&main + (&exit - &main)*(j/1000))(j+1);
es equivalente a:
(&main + (&exit - &main)*0)(j+1);
Cual es:
(&main)(j+1);
Que llama main
con j+1
.
Si j == 1000
, entonces las mismas líneas salen como:
(&main + (&exit - &main)*1)(j+1);
Que se reduce a
(&exit)(j+1);
Que es exit(j+1)
y sale del programa.
(&exit)(j+1)
y exit(j+1)
son esencialmente lo mismo, citando C99 §6.3.2.1 / 4:
Un designador de función es una expresión que tiene tipo de función. Excepto cuando es el operando del operador sizeof o el operador unario y , un designador de función con el tipo " tipo de retorno de función " se convierte en una expresión que tiene el tipo " puntero al tipo de retorno de función ".
exit
es un designador de funciones. Incluso sin la &
dirección unaria del operador, se trata como un puntero para funcionar. (Lo &
justo lo hace explícito).
Y las llamadas a funciones se describen en §6.5.2.2 / 1 y siguientes:
La expresión que denota la función llamada tendrá un puntero de tipo para funcionar devolviendo vacío o devolviendo un tipo de objeto que no sea un tipo de matriz.
Por lo tanto, exit(j+1)
funciona debido a la conversión automática del tipo de función a un tipo de puntero a función, y (&exit)(j+1)
funciona también con una conversión explícita a un tipo de puntero a función.
Dicho esto, el código anterior no es conforme ( main
toma dos argumentos o ninguno), y &exit - &main
creo que no está definido de acuerdo con §6.5.6 / 9:
Cuando se restan dos punteros, ambos apuntarán a elementos del mismo objeto de matriz , o uno más allá del último elemento del objeto de matriz; ...
La adición (&main + ...)
sería válida en sí misma y podría usarse, si la cantidad agregada fuera cero, ya que §6.5.6 / 7 dice:
Para los fines de estos operadores, un puntero a un objeto que no es un elemento de una matriz se comporta igual que un puntero al primer elemento de una matriz de longitud uno con el tipo de objeto como su tipo de elemento.
Por lo tanto, agregar cero a &main
estaría bien (pero no mucho uso).
main
en C ++.