int *shiftRmemmove(int *arr, size_t size)
{
if(arr && size)
{
memmove(arr + size - 1, arr + size - 2, (size - 1) *sizeof(*arr));
arr[0] = 0;
}
return arr;
}
Está definido se size == 1
? Está calculando e passando referência ao elemento do array um * antes do primeiro elemento. é equivalente a: memove(arr, arr -1, 0);
(©Jabberwocky)
Se
arr
for um ponteiro para o primeiro elemento de uma matriz e sesize
for 1, mesmo a tentativa de formar o endereçoarr + size - 2
é um comportamento indefinido. Isso está explicado na Norma C (C23 Draft Standard 6.5.6 9):Conforme mencionado no padrão C cap. 7.24.1 subcláusula 2 (aplica-se a todas as funções em
<string.h>
- grifo meu):então você está formando uma chamada:
onde o segundo argumento (ponteiro) não tem valor válido. O padrão proíbe explicitamente a formação de tais ponteiros, uma vez que o capítulo 7.1.4 (apontado pela primeira citação) menciona que:
Veredicto: o padrão proíbe explicitamente isso. O comportamento é indefinido.
arr
é um ponteiro, mas, a partir dos comentários, pretendemos assumir que ele aponta para o elemento 0 de algum arrayA
.Considere a expressão
arr + size - 2
.arr + size
é incontroverso; aponta para&A[1]
, mesmo queA
seja um array de 1 elemento, então esse&A[1]
é o endereço “logo além” do último elemento do array.Para
arr + size - 2
, efetivamente&A[1] - 2
, consideramos C 2018 6.5.6 8:Esta passagem não define o resultado
&A[1] - 2
porque o elemento do arrayA
com índice −1 não existe. Isto por si só é suficiente para tornar o comportamento não definido, porque nada mais na norma o define, e C 2018 4 2 nos diz “O comportamento indefinido é indicado de outra forma neste documento… pela omissão de qualquer definição explícita de comportamento”. No entanto, 6.5.6 8 continua:Aqui o operando ponteiro (
&A[1]
) e o resultado (&(A[-1]
) não apontam para elementos do mesmo objeto array ou de um objeto anterior a ele, portanto o comportamento é indefinido.A avaliação de
arr + size - 2
ocorre antesmemmove
de ser chamada, portanto, sememmove
usa seu parâmetro correspondente é irrelevante; o comportamento já está indefinido.