¿El mandato de normalización de un lvalue-a-r-value de la conversión de la variable de puntero al aplicar el direccionamiento indirecto?

StackOverflow https://stackoverflow.com//questions/21053273

Pregunta

TL;DR

Dado el siguiente código:

int* ptr;
*ptr = 0;

¿ *ptr requieren de un lvalue-a-r-value la conversión de ptr antes de aplicar el direccionamiento indirecto?

El estándar cubre el tema de la lvalue-a-r-value en muchos lugares, pero no parece para especificar la información suficiente para determinar si el * operador requieren de este tipo de conversión.

Detalles

El lvalue-a-r-value la conversión es cubierto en N3485 en la sección 4.1 Lvalue-a-r-value de conversión párrafo 1 y dice (el énfasis es mío adelante):

Un glvalue (3.10) de un no-función, no de la matriz de tipo T se puede convertir a un prvalue.53 Si T es un tipo incompleta, un programa que requiere esta conversión está mal formado.Si el objeto al que el glvalue se refiere no es un objeto de tipo T y no es un objeto de una tipo derivado de T, o si el objeto no está inicializada, un programa de que requiere esta conversión tiene un comportamiento indefinido.[...]

Lo hace *ptr = 0; requieren esta conversión?

Si nos vamos a la sección 4 párrafo 1 dice:

[...]Un estándar de conversión de la secuencia se aplica a una expresión si es necesario para convertir un tipo de destino.

Así que cuando es es necesario?Si nos fijamos en la sección 5 Expresiones el lvalue-a-r-value la conversión se menciona en el párrafo 9 que dice:

Cada vez que un glvalue expresión aparece como un operando de un operador que espera un prvalue para que operando, el lvalue-a-r-value (4.1), matriz-a-puntero (4.2), o la función-a-puntero (4.3) estándar las conversiones se aplica para convertir la expresión en una prvalue.[...]

y en el párrafo 11 que dice:

En algunos contextos, una expresión que sólo aparece para sus efectos secundarios.Tal expresión se llama descartado-expresión de valor.[...] La lvalue-a-r-value de conversión (4.1) se aplica si y sólo si el la expresión es un lvalue de la volatilidad de tipo completo y es uno de la siguiente [...]

ni el párrafo parece aplicar a este código de ejemplo y 5.3.1 Operadores unarios párrafo 1 dice:

La unario * operador realiza el direccionamiento indirecto:la expresión con la que se es aplicado debe ser un puntero a un tipo de objeto, o un puntero a una tipo de función y el resultado es un lvalue haciendo referencia al objeto o función a la que la expresión de puntos.Si el tipo de la expresión es "puntero a T", el tipo del resultado es "T." [ Nota:direccionamiento indirecto a través de un puntero a un tipo incompleta (aparte de cv void) es válida.El lvalue así obtenido puede ser utilizado de manera limitada (para inicializar un de referencia, por ejemplo);este lvalue no debe ser convertido a un prvalue, consulte la sección 4.1.—nota final ]

no parece requerir la valor de el puntero y no veo los requisitos para una conversión del puntero aquí que me estoy perdiendo algo?

¿Por qué nos preocupamos?

He visto una respuesta y comentarios de otras preguntas que exigen el uso de un puntero sin inicializar es un comportamiento indefinido debido a la necesidad de un lvalue-a-r-value la conversión de ptr antes de aplicar el direccionamiento indirecto.Por ejemplo: Donde se hace exactamente el estándar de C++ decir desreferenciar un puntero sin inicializar es un comportamiento indefinido? hace que este argumento y no puedo conciliar el argumento con lo dispuesto en cualquiera de las recientes versiones de borrador de la norma.Ya he visto esto varias veces que me quería obtener una aclaración.

La prueba real de un comportamiento indefinido no es tan importante, ya que como he dicho en la pregunta vinculada tenemos encima de otros para llegar a un comportamiento indefinido.

¿Fue útil?

Solución 2

He convertido a la sección de actualización en mi pregunta para una respuesta ya que en este momento parece ser la respuesta, aunque de una forma poco satisfactoria que mi pregunta es incontestable:

dyp me señaló a dos relevantes hilos que cubren muy similares:

El consenso parece ser que la norma es mal especificado y por lo tanto no puede proporcionar la respuesta que estoy buscando, José Mansfield publicado un informe de defecto en esta falta de especificación, y parece que todavía es abierto y no está claro cuándo puede ser aclarado.

Hay un par de sentido común argumentos como para la la intención de la norma.Uno puede argumentar Logicially, un operando es un prvalue si la operación requiere el uso del valor de operando.Otro argumento es que, si miramos a la C99 proyecto de norma dice un lvalue a r-value conversión se realiza de forma predeterminada y las excepciones que se indican.La sección pertinente en el borrador del estándar C99 es 6.3.2.1 Lvalues, matrices, y la función de designadores párrafo 2 que dice:

Excepto cuando es el operando del operador sizeof, la unario & operador, el operador++, -- el operador, o el de la izquierda el operando de la .operador o de un operador de asignación, un lvalue que no tiene tipo de matriz se convierte en el valor almacenado en la zona de objeto (y no es un lvalue).[...]

lo que básicamente dice que con algunas excepciones, un operando se convierte en el valor almacenado y ya direccionamiento indirecto no es una excepción si esto se aclara también el caso en C++ así entonces sería, de hecho, que la respuesta a mi pregunta .

Como he tratado de aclarar la prueba de un comportamiento indefinido fue menos importante que en la clarificación de si un lvalue-a-r-value de conversión es obligatoria.Si queremos demostrar un comportamiento indefinido hemos enfoques alternativos.Jerry es un sentido común de uno y en que direccionamiento indirecto requiere que la expresión a ser un apuntador a un objeto o una función y un valor indeterminado sólo por accidente apuntan a un objeto válido. En general el proyecto de C++ estándar no proporciona una declaración explícita de decir, usando un indeterminado valor es undefined, a diferencia de la C99 proyecto de norma En C++11 y la espalda de la norma no da una declaración explícita decir, usando un indeterminado valor es undefined.Con la excepción de los iteradores y, por extensión, punteros tenemos el concepto de valor singular y se nos dice en la sección 24.2.1 que:

[...][ Ejemplo:Después de la declaración de un puntero sin inicializar x (como int* x;), x debe ser siempre supone que tienen un valor singular de un puntero.—fin del ejemplo ] [...] Dereferenceable valores son siempre no-singular.

y:

Un inválido iterador es un iterador que puede ser singular.268

y la nota de pie de página 268 dice:

Esta definición se aplica a los punteros, ya que los punteros son iteradores.El efecto de eliminar un iterador que ha sido invalidado es indefinido.

En C++1y los cambios de idioma y tenemos una declaración explícita de lo que el uso de un valor intermedio indefinido con algunas pocas excepciones.

Otros consejos

Creo que lo aborda desde un lugar ángulo oblicuo, por así decirlo.De acuerdo con el §5.3.1/1:

La unario * operador realiza direccionamiento indirecto:la expresión a la que se aplica debe ser un puntero a una tipo de objeto, o un puntero a un tipo de función y el resultado es un lvalue haciendo referencia al objeto o función para que la expresión de puntos.Si el tipo de la expresión es "puntero a T", el tipo del resultado es "T".

A pesar de esto no habla de la lvalue-a-r-value de conversión, se requiere que la expresión a ser un apuntador a un objeto o función.Un puntero sin inicializar no (excepto, tal vez por accidente) ser cualquier cosa de modo que el intento de eliminar la referencia da un comportamiento indefinido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top