es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Realizar indirección desde un puntero adquirido al convertir un valor entero, ¿está definitivamente indefinido (UB, por sus siglas en inglés)?

Considere este ejemplo

int main(){
  std::intptr_­t value = /* un valor entero especial */; 
  int* ptr = reinterpret_­cast<int*>(value ); // #1
  int v = *ptr;  // #2
}

[expr.reinterpret.cast] p5 dice

Un valor de tipo entero o tipo enumerado puede ser convertido explícitamente a un puntero. Un puntero convertido a un entero de tamaño suficiente (si existe alguno en la implementación) y devuelto al mismo tipo de puntero tendrá su valor original; las asignaciones entre punteros e enteros de otra manera están definidas por la implementación.

Al menos, el paso #1 es definido por la implementación. Para el paso #2, en mi opinión, creo que existen cuatro posibilidades, las cuales son

  1. La implementación no soporta dicha conversión y la implementación hace cualquier cosa para ello.
  2. El valor del puntero es exactamente la dirección de un objeto de tipo int, el resultado es válido.
  3. El valor del puntero es la dirección de un objeto que no es de tipo int, el resultado es comportamiento indefinido.
  4. El valor del puntero es un valor de puntero no válido, el indirecto es comportamiento indefinido.

Esto significa que el comportamiento de la indirección a través del puntero ptr depende de la implementación. No es definitivamente comportamiento indefinido si la implementación toma la opción 2. Entonces, me pregunto si este caso es definitivamente comportamiento indefinido o no. Si es lo último, ¿qué provisiones declaran claramente el comportamiento?

Tags:  ,

Answer

  1. Avatar for davy.ai

    De acuerdo al ejemplo dado y al estándar [expr.reinterpret.cast] p5, el comportamiento de la indirección a través del puntero ptr es indefinido por implementación. Por lo tanto, no se puede afirmar con certeza si es definitivamente UB o no. Puede depender de la implementación del compilador que se esté utilizando. Por lo tanto, no se puede confiar en el mismo comportamiento en diferentes plataformas.

    Sin embargo, si la implementación no admite la conversión o el valor del puntero es la dirección de un objeto que no sea del tipo int o es un valor de puntero no válido, entonces la indirección es definitivamente UB. Esto se debe a que acceder a un objeto a través de dichos punteros violaría las reglas de estricta alineación definidas por el estándar [basic.lval] p10.

    En general, es importante tener precaución al usar reinterpret_cast y asegurarse de que se use solo según las pautas estándar para evitar tales comportamientos indefinidos.

Comments are closed.