gpt4 book ai didi

c - C 中的严格别名违规以及如何编写符合要求的代码?

转载 作者:行者123 更新时间:2023-12-04 00:12:24 26 4
gpt4 key购买 nike

下面看到的代码是在某些竞技场实现中看到的典型代码。一个这样的示例可以找到 here (关于示例 impl 的博客文章。)。

#include<stdio.h>
#include<stdint.h>
#include<stdalign.h>

struct thing {
int a;
int b;
};

char buffer[128];

int main ()
{

uintptr_t p1 = (uintptr_t)buffer;
if (p1 % alignof(struct thing)) return 1;

struct thing *t1 = (void*)buffer;
t1->a = 10;
t1->b = 20;

uintptr_t p2 = (uintptr_t)(buffer + sizeof(struct thing));
if (p2 % alignof(struct thing)) return 1;

struct thing *t2 = (void*)(buffer + sizeof(struct thing));
t2->a = 30;
t2->b = 40;


printf("%d\n",t1->a);
printf("%d\n",t2->a);

return 0;
}

编辑的代码:如果任何指针缺少正确对齐,则使程序返回 1

  1. 这是一个严格的别名违规的实例,并且...
  2. 将此类结构放入缓冲区并检索安全以使用指向该结构的指针的唯一方法是:

struct thing *t1 = memcpy(buffer,&((struct thing){10,20}),sizeof(struct thing));

最佳答案

Is this an instance of a strict aliasing violation

是的。 t1->a 等通过与“有效类型”(char)不同的类型访问字符数组。

Is the only way to place such structures in a buffer and to retrieve a safe to use pointer to the structure to do for example:

您还可以创建原始字符数组和要转换为的类型的 union 。示例:

typedef union
{
struct thing t;
char buf[128];
} strict_aliasing_hack;

...

strict_aliasing_hack thing t1 = *(strict_aliasing_hack*)buffer;

这没关系,因为 strict_aliasing_hack 是“一种聚合或 union 类型,其中包含一个与其成员中的对象的有效类型兼容的类型”(C17 6.5/7)。

当然,最好完全避免这种可疑的转换。例如,从 malloc 返回的数据 block 没有有效类型。所以原代码最好写成:

struct thing *t1 = malloc(128);

现在你可以用任何你喜欢的方式左值访问*t1

关于c - C 中的严格别名违规以及如何编写符合要求的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68224779/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com