将数组转换为具有一个数组作为成员的结构是否安全?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将数组转换为具有一个数组作为成员的结构是否安全?相关的知识,希望对你有一定的参考价值。

在以下设置中

typedef struct {
    unsigned char data[64];
} mystruct;

int myfunc(mystruct* arg); // fills arg with data

使用指向64字节数组的指针调用myfunc是否安全?例如。

unsigned char buffer[64];
myfunc((mystruct*) buffer)

在我的具体应用程序中,我使用的是JNI直接ByteBuffer,应该从myfunc填充。

unsigned char* dbbuffer = (unsigned char*) (*env)->GetDirectBufferAddress(env, jbuffer);

如果演员不安全,我将不得不创建一个mystruct,调用myfunc然后memcopydbbuffer,我想避免。

答案

从技术上讲,它可以工作,你可以使用它。正如评论中所指出的,ANSI标准的相关部分是:

6.7.2.1:结构和联合说明符

...指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。结构对象中可能存在未命名的填充,但不是在其开头。

在这种情况下,严格的混叠无关紧要。严格别名规则指定在哪种情况下可以通过更改另一种类型的值来更改某种类型的值。这条规则的主要兴趣是像intfloat这样的标量类型。在您的特定情况下,很明显,通过更改结构的成员(unsigned char []),您可以更改整个结构,反之亦然。

此案例由严格别名规则的第5个子案例涵盖。为了完整起见,我引用整个部分:

6.5表达式,第7页

对象的存储值只能由具有以下类型之一的左值表达式访问(此列表的目的是指定对象可能或可能没有别名的情况):

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

- 与对象的有效类型兼容的类型的限定版本,

- 对应于对象的有效类型的有符号或无符号类型的类型,

- 对应于对象有效类型的限定版本的有符号或无符号类型,

- 聚合或联合类型,其成员中包含上述类型之一(包括递归地,子聚合或包含联合的成员),或者

- 角色类型

聚合类型的定义在:

6.2.5类型,第21页

算术类型和指针类型统称为标量类型。数组和结构类型统称为聚合类型。

以上是关于将数组转换为具有一个数组作为成员的结构是否安全?的主要内容,如果未能解决你的问题,请参考以下文章

将二维数组分配为结构成员

如何将具有元素数组的每个对象的对象列表转换为具有子元素作为属性的对象数组

如何将结构数组里的两个成员位置交换

Swig:将成员变量(指向值的指针)转换为 python 列表

将C结构转换为具有较少元素的另一个结构是否安全?

具有原始类型的单个数组成员的标准布局结构的保证内存布局