c++ c gcc strict-aliasing

Reglas estrictas de alias de C99 en C++(GCC)



strict-aliasing (3)

El concepto es el mismo en Cpp; en que puede usar modelos de estilo C para guiarlo a través de lo que se considera seguro y estricto aliasing.

En resumen: no, el enfoque para usar el casting de Cpp (que usted ha descrito) no cubrirá todos los casos de manera segura. Una forma común de romper las reglas es usar static_cast para lanzar punteros.

Simplemente encienda las advertencias del compilador: le indicará (o debería ) lo que no es seguro.

Según tengo entendido, GCC es compatible con todas sus funciones C99 en C ++. Pero, ¿cómo se maneja el aliasing estricto de C99 en el código C ++?

Sé que la conversión con modelos de C entre tipos no relacionados no es estricta aliasing y puede generar código incorrecto, pero ¿qué pasa con C ++? Como el aliasing estricto no es parte del estándar de C ++ (¿es correcto?), GCC debe especificar la semántica en sí.

const_cast que const_cast y static_cast emiten entre tipos relacionados, por lo tanto, son seguros, mientras que reinterpret_cast puede romper las reglas estrictas de alias.

¿Es esta una comprensión correcta?


No, probablemente estés mezclando cosas diferentes.

Las reglas estrictas de aliasing no tienen absolutamente nada que ver con el estándar C99 específicamente. Las reglas de alias estrictas están arraigadas en partes del estándar que estaban presentes en C y C ++ desde el comienzo de los tiempos [estandarizados]. La cláusula que prohíbe acceder a un objeto de un tipo a través de un valor de otro tipo está presente en C89 / 90 ( 6.3 ) así como en C ++ 98 ( 3.10 / 15 ). De eso se trata el aliasing estricto, ni más ni menos. Es solo que no todos los compiladores querían (o se atrevieron) hacerla cumplir o confiar en ella. Los lenguajes C y C ++ a veces se usan como lenguajes de "ensamblaje de alto nivel" y las reglas estrictas de alias a menudo interfieren con tales usos. Fue GCC quien hizo ese movimiento audaz y decidió comenzar a confiar en las reglas estrictas de alias en las optimizaciones, a menudo generando quejas de esos tipos de "ensamblaje".

Es cierto que la forma más sencilla de romper las reglas estrictas de alias en C ++ es reinterpret_cast (y, por supuesto, el estilo C). Sin embargo, static_cast también se puede usar para ese propósito, ya que permite romper un alias estricto usando void * como un tipo intermedio en un cast "encadenado"

int *pi; ... double *pd = static_cast<double *>(static_cast<void *>(pi));

const_cast no puede romper el alias estricto en un compilador compatible.

En cuanto a C99 ... Lo que C99 introdujo fue el calificador de restrict . Esto está directamente relacionado con el aliasing, pero no es lo que se conoce como aliasing estricto per se.


static_cast puede romper las reglas de aliasing, porque el compilador confía en usted para asegurarse de que el tipo de destino esté relacionado con el tipo de tiempo de ejecución real del objeto. Considerar:

extern void f(double*, int*); // compiler may optimize assuming that arguments don''t overlap double d; void* pv = &d; int* pi = static_cast<int*>(pv); f(&d, pi); // assumption is violated