将数组强制转换为以一个数组为成员的结构是否安全? [英] Is it safe to cast an array to a struct with one array as member?

查看:102
本文介绍了将数组强制转换为以一个数组为成员的结构是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下设置中

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

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

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

is it safe to call myfunc with a pointer to a 64 byte array? E.g.

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

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

In my concrete application I am using a JNI direct ByteBuffer which should be filled from myfunc.

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

如果强制转换不安全,则必须创建一个mystruct,先调用myfunc,然后调用memcopydbbuffer,这是我想避免的.

If the cast is not safe, I would have to create a mystruct, call myfunc and then memcopy to dbbuffer, which I would like to avoid.

推荐答案

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

Technically it works and you can use it. As pointed in comments the relevant part of the ANSI standard is:

6.7.2.1:结构和联合说明符

6.7.2.1: Structure and union specifiers

...指向a的指针 经过适当转换的结构对象指向其初始成员(或者该成员是 位域,然后到它所在的单元),反之亦然.可能有未命名 在结构对象中填充,而不是在其开头填充.

... A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

在这种情况下,严格的别名并不重要. 严格的别名规则指定在哪种情况下可以通过更改另一种类型的值来更改某种类型的值.此规则的主要目的是标量类型,例如intfloat.在您的特定情况下,很明显,通过更改结构的成员(unsigned char []),您会更改整个结构,反之亦然.

The strict aliasing does not matter in this case. Strict aliasing rule specifies in which circumstances a value of some type can be changed by changing a value of another type. The main interest of this rule are scalar types like int and float. In your particular case it is evident that by changing a member of a struct (unsigned char []) you change the whole structure and vice versa.

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

This case is covered by the 5th subcase of the strict aliasing rule. I quote the whole part for the sake of completeness:

6.5表达式,第7页

6.5 Expressions, p.7

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

An object shall have its stored value accessed only by an lvalue expression that has one of the following types (The intent of this list is to specify those circumstances in which an object may or may not be aliased):

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

— a type compatible with the effective type of the object,

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

— a qualified version of a type compatible with the effective type of the object,

-一种类型,是与有效类型相对应的有符号或无符号类型 对象

— a type that is the signed or unsigned type corresponding to the effective type of the object,

-一种类型,它是与标准版本对应的有符号或无符号类型 对象的有效类型,

— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,

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

— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or

-字符类型

其中 aggegate类型的定义位于:

6.2.5类型,第21页

6.2.5 Types, p.21

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

Arithmetic types and pointer types are collectively called scalar types. Array and structure types are collectively called aggregate types.

这篇关于将数组强制转换为以一个数组为成员的结构是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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