Tengo curiosidad acerca de las convenciones para los punteros tipo-punning/matrices en C++. Aquí está el caso de uso que tengo en este momento:Opiniones sobre tipo-juego de palabras en C++?
Calcule una suma de comprobación simple de 32 bits sobre un conjunto binario de datos al tratarlo como una matriz de enteros de 32 bits (sabemos que su longitud total es un múltiplo de 4), y luego resumir todos los valores e ignorar el desbordamiento.
Yo esperaría una función de este tipo de aspecto:
uint32_t compute_checksum(const char *data, size_t size)
{
const uint32_t *udata = /* ??? */;
uint32_t checksum = 0;
for (size_t i = 0; i != size/4; ++i)
checksum += udata[i];
return udata;
}
Ahora la pregunta que tengo es, ¿qué se tiene en cuenta la "mejor" para convertir a data
udata
?
C-style cast?
udata = (const uint32_t *)data
C++ cast que supone que todos los punteros son convertibles?
udata = reinterpret_cast<const uint32_t *>(data)
C++ fundido que entre tipos de puntero arbitrarias usando el Intermedio void*
?
udata = static_cast<const uint32_t *>(static_cast<const void *>(data))
¿Echar a través de una unión?
union {
const uint32_t *udata;
const char *cdata;
};
cdata = data;
// now use udata
Soy plenamente consciente de que esto no será una solución portátil 100%, pero sólo estoy esperando a usarlo en un pequeño conjunto de plataformas en el que sé que funciona (memoria a saber, no alineada accesos y supuestos compilador de puntero aliasing). ¿Qué recomendarías?
las soluciones de litb son correctas según el estándar, pero como ya he dicho, ya estoy buscando plataformas específicas. – Tom
no estoy seguro de por qué rechazaron esto :) pero tampoco estoy seguro de que mi uso de la unión sea un comportamiento indefinido. Soy consciente de que escribir a un miembro y leer de otro miembro es un comportamiento indefinido. Pero en mi caso, estoy apuntando a un miembro de él, que se supone que tiene un valor válido, y lo leí luego. –
No creo que este ejemplo en particular rompa el alias estricto. char * es un caso especial bajo estrictas reglas de aliasing - un char * nunca se puede suponer, no un alias de un puntero a algún otro tipo. Pero en mi respuesta todavía juego seguro: simplemente no vale la pena hacer char * de manera diferente a otros casos similares. –