对字符数组结构成员进行类型双关

问题描述

考虑以下代码:

typedef struct { char byte; } byte_t;
typedef struct { char bytes[10]; } blob_t;

int f(void) {
  blob_t a = {0};
  *(byte_t *)a.bytes = (byte_t){10};
  return a.bytes[0];
}

这是否会在 return 语句中产生别名问题?您确实让 a.bytes 取消引用了在 patch 中没有别名赋值的类型,但另一方面,[0] 部分取消引用了一个有别名的类型。

我可以构建一个稍微大一点的例子,其中 gcc -O1 -fstrict-aliasing 确实使函数返回 0,我想知道这是否是 gcc 错误,如果不是,我可以做些什么来避免这个问题(在我的实际示例中,赋值发生在一个单独的函数中,因此这两个函数孤立地看起来真的很无辜)。

这是一个更长更完整的测试示例:

#include <stdio.h>

typedef struct { char byte; } byte_t;
typedef struct { char bytes[10]; } blob_t;

static char *find(char *buf) {
    for (int i = 0; i < 1; i++) { if (buf[0] == 0) { return buf; }}
    return 0;
}

void patch(char *b) { 
    *(byte_t *) b = (byte_t) {10}; 
}

int main(void) {
    blob_t a = {0};
    char *b = find(a.bytes);
    if (b) {
        patch(b);
    }
    printf("%d\n",a.bytes[0]);
}

使用 gcc -O1 -fstrict-aliasing 构建会产生 0

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)