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
- La implementación no soporta dicha conversión y la implementación hace cualquier cosa para ello.
- El valor del puntero es exactamente la dirección de un objeto de tipo
int
, el resultado es válido.- El valor del puntero es la dirección de un objeto que no es de tipo
int
, el resultado es comportamiento indefinido.- 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?
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.