我正在分析一些代码,其中包括(简化后)以下 struct :

struct some_array {
    void *elements;
    int nof_elements;
    bool has_pointers;
};

elements成员可以是my_type个元素的数组,也可以是指向my_type个元素的指针array.两者中的哪一个,取决于has_pointers的值.

在堆上分配elements个数组内容,例如:

    struct some_array arr = {.nof_elements = 10};
    arr.has_pointers = false;
    arr.elements = malloc(arr.nof_elements * sizeof(my_type));

    struct some_array arr = {.nof_elements = 10};
    arr.has_pointers = true;
    arr.elements = malloc(arr.nof_elements * sizeof(my_type *));
    f或 (size_t i=0; i<arr.nof_elements; i++) {
        ((my_type**)arr.elements)[i] = malloc(sizeof(my_type));
    }

The access logic f或 the ith element is like this:

my_type *elmt;
if (arr->has_pointers) {
    elmt = ((my_type **)arr->elements)[i];
} else {
    elmt = &((my_type *)arr->elements)[i];
}

Assuming that the has_pointers member is properly set acc或ding to the actual contents of elements, this seems w或k fine. But it is not clear to me whether this construct complies with the strict aliasing rule? Does it comply with this prescription in the C language specification?

An object shall have its st或ed value accessed only by an lvalue expression that has one of the following types:

-与对象的有效类型兼容的类型,

在这种情况下,我很难适用effective type的定义,我在这句话中找不到compatible的含义的定义.

推荐答案

您所做的是not个严格的锯齿冲突,并且实际上定义得很好.

在第一种情况下:

struct some_array arr = {.nof_elements = 10};
arr.has_pointers = false;
arr.elements = malloc(arr.nof_elements * sizeof(my_type));

对于一个包含my_type个数组的数组,arr.elements个点指向空格.通过malloc获得的内存可针对任何目的进行适当的对准,因此不存在对准问题.将值arr.elements正确地转换为类型my_type *允许您访问该时间的array.

第二种情况也是如此:

struct some_array arr = {.nof_elements = 10};
arr.has_pointers = true;
arr.elements = malloc(arr.nof_elements * sizeof(my_type *));
for (size_t i=0; i<arr.nof_elements; i++) {
    ((my_type**)arr.elements)[i] = malloc(sizeof(my_type));
}

对于一个包含my_type *个数组的数组,arr.elements个点指向空格.然后将其强制转换为该类型my_type *,以正确地允许访问该类型的数组并赋值.

然后,当您稍后执行此操作时:

my_type *elmt;
if (arr->has_pointers) {
    elmt = ((my_type **)arr->elements)[i];
} else {
    elmt = &((my_type *)arr->elements)[i];
}

第一部分没有问题,因为arr->elements被视为my_type *的数组,并再次以这种方式使用,并且该数组的一个元素被分配给elmt.类似地,第二部分也可以,因为arr->elements被视为my_type的数组,并且该数组的元素的地址被分配给elmt.

C++相关问答推荐

在严格的C89模式下,收件箱不会在' uint64_t '上发出警告

如何在C中的空指针函数中传递浮点值

为什么这个select()会阻止?

无效使用未定义类型'structsquare'?

二进制计算器与gmp

Setenv在c编程中的用法?

GCC创建应用于移动项的单独位掩码的目的是什么?

Square不与Raylib一起移动

在另一个函数中使用realloc和指针指向指针

错误...的多个定义(&Q)首先在这里定义&

Wcstok导致分段故障

如何在C中定义指向函数的指针并将该指针赋给函数?

在C中使用无符号整数模拟有符号整数

UpDown控制与预期相反

将char*铸造为空**

与指针的原始C数组或C++向量<;向量<;双>>;

WSASocket在哪里定义?

一元运算符

函数的typedef是标准 C 语法吗?它与函数指针的typedef有何不同?

使用复合文字数组初始化的指针数组