Я хочу суммировать все байты моей структуры. Я прочитал, что должен привести указатель моей структуры от символа к короткому. Почему?

Правильно ли использовать приведение (short) от char к short?

Мой код

#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;
}

Похоже, это работает, но я не могу это проверить. Любая помощь приветствуется.

c++ c
0
bielu000 4 Мар 2018 в 10:28

4 ответа

Лучший ответ

Нет, поведение при разыменовании указателя, установленного на результат приведения из char* к short*, равно undefined , если только данные, к которым {{X2} } указывает, что изначально был short объектом или массивом; который твой не.

Четко определенный способ (как в C, так и в C ++) для анализа памяти заключается в использовании unsigned char*, но будьте осторожны, чтобы не перебрать вашу память, чтобы достичь областей, которые не принадлежат вашей программе.

3
Bathsheba 4 Мар 2018 в 07:36

В основном это работает, потому что вы очистили структуру с нуля. = {0}.
Вы можете дать функции указатель на структуру struct * pseudo_header.

Я бы увидел вопрос выравнивания.

Я бы проверил sizeof (struct ..) на ожидаемое значение 33, если мне нужно добавить прагму pack () перед структурой и затем привести к unsigned char * внутри функции.

Проверьте свою функцию с именем длиной 25 символов.

1
Mark1104 4 Мар 2018 в 08:11

Приведение (псевдоним) указателя к любому типу, кроме char *, нарушает строгое правило псевдонимов. Gcc оптимизирует, основываясь на предположениях о строгом правиле псевдонимов, и может привести к интересным ошибкам. Единственный действительно безопасный способ обойти строгое правило наложения имен - использовать memcpy. Gcc поддерживает memcpy как встроенную функцию компилятора, поэтому может оптимизировать копию.

Кроме того, вы можете отключить строгое псевдонимы с помощью флага -fno-strict-aliasing.

PS - Мне неясно, обеспечивает ли профсоюз подходящий способ обхода строгого правила алиасинга.

0
doron 4 Мар 2018 в 08:20

short не менее двух байтов. Так что если вы хотите суммировать все байты, приведение к short* неверно. Вместо этого приведите к unsigned char*.

0
john 4 Мар 2018 в 07:35