c - C 中的严格别名违规以及如何编写符合要求的代码?
问题描述
下面看到的代码是在某些 arena 实现中看到的典型代码。可以在此处找到一个这样的示例(有关示例 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
- 这是一个严格的混叠违规的实例,并且......
- 是将此类结构放置在缓冲区中并检索安全以使用指向该结构的指针的唯一方法,例如:
struct thing *t1 = memcpy(buffer,&((struct thing){10,20}),sizeof(struct thing));
解决方案
问题在于,按照标准,只能以这种方式使用动态内存。
第 5 条表达式说(C11 的参考 n1570):
§6 访问其存储值的对象的有效类型是对象的声明类型,如果有的话。
如果您使用:
void * buffer = malloc(128);
那么 buffer 保证具有与任何标准类型兼容的对齐方式并且没有声明的类型。
在这种情况下,您可以安全地将thing
对象存储在缓冲区中,而不会触发任何严格的别名违规。但是在您的示例代码中,buffer
声明的类型是char
. 无论对齐方式如何,使用不同的类型都是严格的别名违规。
推荐阅读
- javascript - 在普通的 VueJS 项目中使用 Typescript 函数
- sql - 将 SQL 中第一个字符之后的所有内容更新为小写?
- wkhtmltopdf - wkhtmltopdf 显示黑框而不是文本
- javascript - 解决无法集中读取未定义的属性“propertyName”
- sql - 在VB6中我们需要使用哪些adodb记录集选项来在短时间内从SQL中加载数据
- sql - 将记录链接到其他人
- c# - 如何用星号打印星号图案
- ios - 如何在点击的光线触摸而不是来自中心视图的光线处生成 Reality Composer 场景
- apache - 确定原因并修复 302 重定向
- word2vec - 为什么“[UNK]”这个词在 word2vec 词汇表中排在第一位?