Pregunta

Tengo una función que toma un entero largo sin signo * y las necesidades de pasarlo a una biblioteca externa que toma un entero sin signo * y en esta plataforma unsigned int / larga son del mismo tamaño.

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable
}

Esto genera una advertencia diciendo que su romper las reglas estrictas-aliasing. ¿Hay arounds de trabajo?

Gracias

Edit: Me disculpo por no ser clara. El código es una actualización atómica por lo que va alrededor de la biblioteca para almacenar no es una opción. Podría bajar hasta el montaje, pero me gustaría hacer esto en C ++.

¿Fue útil?

Solución

void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}

Otros consejos

Esto debería funcionar:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}

No hay nada en los mandatos C estándar que int y long deben tener el mismo tamaño; Además, incluso si lo hacen tienen el mismo tamaño, nada en los mandatos estándar que tienen la misma representación (entre otras cosas, que podrían tener las combinaciones incompatibles de bits de relleno y representaciones trampa, de tal manera que aliasing entre los dos tipos no podía servir a cualquier propósito útil).

Los autores de la Norma no quería a los ejecutores de la fuerza de orientación plataformas donde aliasing entre int y long no tendría ninguna utilidad para reconocer tales aliasing. También no quieren escribir reglas que serían aplicables a algunas plataformas (aquellos donde aliasing serviría a un propósito), pero no en otros (aquellos en los que no lo haría). En su lugar, se dieron cuenta de que las personas que escriben compiladores de calidad se trate de reconocer aliasing en los casos en los que era útil.

Ser capaz de utilizar punteros a un tipo de 32 bits a leer y escribir valores de otro tipo de 32 bits que tiene la misma representación es claramente útil, sobre todo si las API están divididos en cuanto a qué tipo de lo que esperan. Si algunas API comunes en un int* uso de la plataforma de valores de 32 bits y otros utilizan long*, un Calidad aplicación de propósito general para que la plataforma debe permitir que los datos de cualquier tipo sean accedidos de punteros de la otra.

Por desgracia, sin embargo, los autores de algunos compiladores están más interesados ??en la tramitación de un determinado subconjunto de programas de forma rápida, que en el procesamiento de un subconjunto más grande de los programas de utilidad, y no pueden ser invocados para generar el código de utilidad si es necesario intercambiar datos entre API que utilizan la misma representación de datos, pero diferentes tipos nombrados a menos que se desactiva por completo el análisis aliasing. Por supuesto, si uno está focalización dialectos de C que son adecuados para un uso general en microcontroladores, tales problemas no importan.

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