我想总结一下我结构的所有字节。我读到我应该将我的结构的指针从char转换为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;
}
看起来它有效,但我无法验证这一点。任何帮助表示赞赏。
不,取消引用已设置为从char*
到short*
的强制转换结果的指针的行为是未定义的,除非char*
指向的数据最初是short
对象或数组;你的不是。
用于分析内存的定义良好的方式(在C和C ++中)是使用unsigned char*
,但要注意不要遍历内存以便到达不属于您的程序的区域。
基本上这是有效的,因为你清除了零结构。 = {0}。 您可以为函数指定结构struct * pseudo_header的指针。
我会看到对齐问题。
如果我必须在结构之前添加一个pragma pack()语句,然后在函数内部转换为unsigned char *,我会检查sizeof(struct ..)的期望值33。
使用25个字符长度名称测试您的函数。
short
至少有两个字节。因此,如果你想总结所有字节,那么转换为short*
是错误的。而是投向unsigned char*
。
使用char *
以外的任何类型对指针进行强制转换(别名)违反了严格别名规则。 Gcc将根据严格别名规则的假设进行优化,并可能导致有趣的错误。 Tge只有真正安全的方式绕过严格的别名规则是使用memcpy
。 Gcc支持memcpy作为编译器内在函数,因此可以优化到副本中。
或者,您可以使用-fno-strict-aliasing标志禁用严格别名。
PS - 我不清楚联盟是否提供了一个合适的方法来绕过严格的别名规则。