Quiero resumir todos los bytes de mi estructura. Leí que debería lanzar el puntero de mi estructura de char a short. ¿Por qué?

¿La conversión usando (short) de char a short es correcta?

Mi código

#include <stdio.h>
#include <string.h>

struct pseudo_header
{
    int var1;
    int var2;
    char name[25];
};

void csum(const unsigned short* ptr, int nbytes)
{
    unsigned long sum = 0;

    for(int i = 0; i < sizeof(struct pseudo_header); i++)
    {
        printf("%#8x\n", ptr[i]);
        sum+= ptr[i];
    }

    printf("%#8x", sum);
}

int main() {

    struct pseudo_header psh = {0};
    char datagram[4096];

    psh.var1 = 10;
    psh.var2 = 20;

    strcpy(psh.name, "Test");

    memcpy(datagram, &psh, sizeof(struct pseudo_header));

    csum((unsigned short*)datagram, sizeof(struct pseudo_header));

    return 0;
}

Parece que funciona, pero no puedo verificar esto. Cualquier ayuda es apreciada.

c++ c
0
bielu000 4 mar. 2018 a las 10:28

4 respuestas

La mejor respuesta

No, el comportamiento al desreferenciar un puntero que se ha establecido en el resultado de una conversión de un char* a un short* es indefinido , a menos que los datos a los que {{X2} } está apuntando era originalmente un objeto o matriz short; que el tuyo no es.

La forma bien definida (tanto en C como en C ++) de analizar la memoria es usar un unsigned char*, pero tenga cuidado de no atravesar su memoria para llegar a áreas que no son propiedad de su programa.

3
Bathsheba 4 mar. 2018 a las 07:36

Básicamente esto funciona porque borraste la estructura con cero. = {0}.
Puede asignar a la función un puntero a una estructura struct * pseudo_header.

Vería un problema de alineación.

Verificaría sizeof (struct ..) para el valor esperado 33 si tengo que agregar una instrucción pragma pack () antes de la estructura y luego convertirlo en char * sin signo dentro de la función.

Pruebe su función con un nombre de longitud de 25 caracteres.

1
Mark1104 4 mar. 2018 a las 08:11

Lanzar (alias) un puntero con cualquier tipo que no sea char * infringe la estricta regla de alias. Gcc se optimizará en función de los supuestos de la estricta regla de alias y puede generar errores interesantes. La única forma segura de evitar la estricta regla de alias es usar un memcpy. Gcc admite memcpy como compilador intrínseco, por lo que puede optimizarse en la copia.

Alternativamente, puede deshabilitar el alias estricto con el indicador -fno-estricto-alias.

PD: no estoy claro si un sindicato proporciona una forma adecuada de evitar la estricta regla de alias.

0
doron 4 mar. 2018 a las 08:20

short tiene al menos dos bytes. Entonces, si desea sumar todos los bytes, la conversión a short* es incorrecta. En su lugar, se envía a unsigned char*.

0
john 4 mar. 2018 a las 07:35