【发布时间】:2021-08-06 22:09:31
【问题描述】:
这是一个严格的别名违规的基本原理是 缓冲区已声明类型 char 数组并被 指向结构的指针
#include<string.h>
#include<stdalign.h>
#include<stdio.h>
struct thing {
int a;
char x;
};
int main() {
char alignas(struct thing) buffer[128];
struct thing s = {10,'a'};
struct thing *ptr = memcpy(buffer,&s,sizeof(struct thing));
// violation at ptr->a
printf("%d\n",ptr->a);
return 0;
}
【问题讨论】:
-
严格的别名违规一般不能静态检测。
-
@Barmar 这里可以推导出
ptr是通过memcpy来自&s,所以指向s。此外,ptr->a在分配了s.a的同一基本块中被访问;数据流分析很容易表明最后存储到ptr->a实际上是到s.a。也许 GCC 根本不会通过memcpy跟踪指针出处。使用memcpy返回值的代码非常少见。 -
如果不使用
memcpy的返回值,而是忽略memcpy 的返回值,然后直接从&s初始化ptr,是否有区别?这个问题的目的是确定是否是这个问题:没有通过memcpy函数跟踪指针数据流。 -
@kaz 作为记录,我在这样做时找不到任何警告的方法
struct thing *ptr = (struct thing*) &buffer[0]; ptr->a = 10; ptr->x = 'a'; -
@anonymouscoward,当
buffer不是数组时会产生警告,有意思...
标签: c strict-aliasing