符合老&QUOT的变种;结构黑客" (?) [英] Conforming variant of the old "struct hack" (?)

查看:119
本文介绍了符合老&QUOT的变种;结构黑客" (?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信我已经找到一种方法来实现的东西,如著名的结构黑客便携式C89。我很好奇,如果这真的是严格遵循C89。

I believe I've found a way to achieve something like the well-known "struct hack" in portable C89. I'm curious if this really strictly conforms to C89.

主要的想法是:我分配内存大到足以容纳一个初​​始结构和数组的元素。确切的大小是(K + N)* sizeof的(array_base_type),其中选择 K K *的sizeof(array_base_type)方式> = sizeof的(the_struct) N 是数组元素的数量

The main idea is: I allocate memory large enough to hold an initial struct and the elements of the array. The exact size is (K + N) * sizeof(array_base_type), where K is chosen so that K * sizeof(array_base_type) >= sizeof(the_struct) and N is the number of array elements.

首先,我解引用了的malloc()指针返回到存储 the_struct ,然后使用指针运算来获得的指针数组的结构体之后开始。

First, I dereference the pointer that malloc() returned to store the_struct, then I use pointer arithmetic to obtain a pointer to the beginning of the array following the struct.

code一号线是胜过千言万语,所以这里是一个最小的实现:

One line of code is worth more than a thousand words, so here is a minimal implementation:

typedef struct Header {
    size_t length;
    /* other members follow */
} Header;

typedef struct Value {
    int type;
    union {
        int intval;
        double fltval;
    } v;
} Value;

/* round up to nearest multiple of sizeof(Value) so that a Header struct fits in */
size_t n_hdr = (sizeof(Header) + sizeof(Value) - 1) / sizeof(Value);

size_t n_arr = 42; /* arbitrary array size here */
void *frame = malloc((n_hdr + n_arr) * sizeof(Value));

if (!frame)
    return NULL;

Header *hdr = frame;
Value *stack_bottom = (Value *)frame + n_hdr;

我最关心的是最后两个任务(使用既是一个指针头和一个指针值)可能违反了严格别名规则。我不这样做,但是,解引用 HDR 为指针,以价值 - 它是在在只进行指针运算为了访问值数组的第一个元素,所以我也不能有效地获取的使用不同类型的指针一样的对象。

My main concern is that the last two assignments (using frame as both a pointer to Header and a pointer to Value) may violate the strict aliasing rule. I do not, however, dereference hdr as a pointer to Value - it's only pointer arithmetic that is performed on frame in order to access the first element of the value array, so I don't effectively access the same object using pointers of different types.

那么,这种方法比任何经典结构更好地破解(已被正式认定为UB),或者是UB呢?

So, is this approach any better than the classic struct hack (which has been officially deemed UB), or is it UB too?

推荐答案

在明显的(嗯......不完全明显,但它就是涉及到的我的的脑海反正:-))的方式造成这种突破是使用矢量编译器,在某种程度上决定是确定以加载,比方说,64 标题 s转换为向量寄存器从42四舍五入先进在 HDR -64+区域这是从的malloc 总是分配足够的量化。存储向量寄存器回内存可能会覆盖取值之一。

The "obvious" (well... not exactly obvious, but it's what comes to my mind anyway :-) ) way to cause this to break is to use a vectorizing compiler that somehow decides it's OK to load, say, 64 Headers into a vector register from the 42-rounded-up-to-64+ area at hdr which comes from malloc which always allocates enough to vectorize. Storing the vector register back to memory might overwrite one of the Values.

我觉得这个量化编译器可能指向标准(当然,如果一个编译器的手指......),并声称一致性。

I think this vectorizing compiler could point to the standard (well, if a compiler has fingers...) and claim conformance.

在实践中,不过,我预计这个code工作。如果你遇到一个量化编译器,增加更多的空间(做与可以插入最小机器相关的宏观四舍五入),并充上。 : - )

In practice, though, I'd expect this code to work. If you come across a vectorizing compiler, add even more space (do the rounding up with a machine-dependent macro that can insert a minimum) and charge on. :-)

这篇关于符合老&QUOT的变种;结构黑客" (?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆