Hmm, eu suspeito que isso é algo que não teria funcionado nos primeiros dias de C. É inteligente, no entanto.
Executando as etapas uma por vez:
&a
obtém um ponteiro para um objeto do tipo int [5]
+1
obtém o próximo objeto, assumindo que há uma matriz desses
*
efetivamente converte esse endereço em ponteiro de tipo para int
-a
subtrai os dois ponteiros int, retornando a contagem de instâncias int entre eles.
Não tenho certeza de que seja completamente legal (neste caso, quero dizer advogado jurídico - não funcionará na prática), considerando algumas operações do tipo em andamento. Por exemplo, você só pode "subtrair" dois ponteiros quando eles apontam para elementos na mesma matriz. *(&a+1)
foi sintetizado acessando outra matriz, embora uma matriz pai, portanto não é realmente um ponteiro para a mesma matriz que a
. Além disso, enquanto você pode sintetizar um ponteiro após o último elemento de uma matriz e pode tratar qualquer objeto como uma matriz de 1 elemento, a operação de dereferencing ( *
) não é "permitida" nesse ponteiro sintetizado, mesmo que não tem comportamento neste caso!
Suspeito que, nos primeiros dias de C (sintaxe K&R, alguém?), Uma matriz se decompôs em um ponteiro muito mais rapidamente, portanto, *(&a+1)
pode retornar apenas o endereço do próximo ponteiro do tipo int **. As definições mais rigorosas do C ++ moderno permitem que o ponteiro para o tipo de matriz exista e saiba o tamanho da matriz, e provavelmente os padrões C seguiram o exemplo. Todo o código de função C usa apenas ponteiros como argumentos, portanto a diferença técnica visível é mínima. Mas estou apenas adivinhando aqui.
Esse tipo de pergunta detalhada sobre legalidade geralmente se aplica a um intérprete C ou a uma ferramenta do tipo fiapo, em vez do código compilado. Um interpretador pode implementar uma matriz 2D como uma matriz de ponteiros para matrizes, porque há menos um recurso de tempo de execução a ser implementado; nesse caso, desmarcando o +1 seria fatal e, mesmo que funcionasse, daria a resposta errada.
Outra possível fraqueza pode ser que o compilador C possa alinhar a matriz externa. Imagine se fosse uma matriz de 5 caracteres ( char arr[5]
), quando o programa o executa &a+1
, está invocando o comportamento da "matriz da matriz". O compilador pode decidir que uma matriz de matriz de 5 caracteres ( char arr[][5]
) é realmente gerada como uma matriz de matriz de 8 caracteres ( char arr[][8]
), para que a matriz externa se alinhe bem. O código que estamos discutindo agora reportaria o tamanho da matriz como 8, e não 5. Não estou dizendo que um compilador em particular faria isso definitivamente, mas poderia.
&a + 1
não está apontando para nenhum objeto válido, portanto é inválido.