Valores que não designam objetos em C ++ 14
Estou usando o N3936 como referência aqui (corrija esta pergunta se algum texto do C ++ 14 for diferente).
Abaixo de 3.10Valores e valores temos:
Toda expressão pertence a exatamente uma das classificações fundamentais nessa taxonomia: lvalue, xvalue ou prvalue.
No entanto, a definição delvalue lê:
Alvalue [...] designa uma função ou um objeto.
Em 4.1Conversão Lvalue para Rvalue o texto aparece:
[...] Em todos os outros casos, o resultado da conversão é determinado de acordo com as seguintes regras: [...] Caso contrário, o valor contido no objeto indicado pelo glvalue é o resultado do prvalue.
Minha pergunta é: o que acontece no código em que o lvalue não designa um objeto? Existem dois exemplos canônicos:
Exemplo 1:
int *p = nullptr;
*p;
int &q = *p;
int a = *p;
Exemplo 2:
int arr[4];
int *p = arr + 4;
*p;
int &q = *p;
std::sort(arr, &q);
Quais linhas (se houver) estão mal formadas e / ou causam comportamento indefinido?
Referindo-se ao Exemplo 1: é*p
um valor? De acordo com minha primeira citação, deve ser. No entanto, minha segunda citação a exclui, pois*p
não designa um objeto. (Certamente também não é um xvalue ou um prvalue).
Mas se você interpretar minha segunda citação, significa que*p
é realmente um lvalue, então não é coberto pelas regras de conversão de lvalue para rvalue. Você pode adotar a regra geral de que "qualquer coisa não definida pelo Padrão é um comportamento indefinido", mas deve permitir a existência de referências nulas, desde que não seja executada nenhuma conversão de valor em valor.
História: Esta questão foi levantada emDR 232 . No C ++ 11, a resolução do DR232 apareceu de fato. Citando N3337Conversão Lvalue para Rvalue:
Se o objeto ao qual o glvalue se refere não for um objeto do tipo T e não for um objeto de um tipo derivado de T ou se o objeto não for inicializado, um programa que necessite dessa conversão terá um comportamento indefinido.
que ainda parece permitir a existência de referências nulas - apenas esclarece o problema de realizar a conversão de lvalue para rvalue em uma.Também discutido neste tópico SO
A resolução do DR232 não aparece mais no N3797 ou N3936.