在以下设置中
typedef struct {
unsigned char data[64];
} mystruct;
int myfunc(mystruct* arg); // fills arg with data
使用指向64字节数组的指针调用myfunc
是安全吗? E.g。
unsigned char buffer[64];
myfunc((mystruct*) buffer)
在我的具体应用程序中,我使用的是JNI直接ByteBuffer,它应该从myfunc
填充。
unsigned char* dbbuffer = (unsigned char*) (*env)->GetDirectBufferAddress(env, jbuffer);
如果演员表不安全,我必须创建一个mystruct
,然后致电myfunc
,然后memcopy
致dbbuffer
,我想避免。< / p>
答案 0 :(得分:2)
技术上它可以工作,你可以使用它。正如评论中所指出的,ANSI标准的相关部分是:
6.7.2.1:结构和联合说明符
...指向a的指针 结构对象,适当转换,指向其初始成员(或者如果该成员是a 位字段,然后到它所在的单元,反之亦然。可能有未命名的 在结构对象中填充,但不在其开头。
在这种情况下,严格别名无关紧要。
严格别名规则指定在哪种情况下可以通过更改另一种类型的值来更改某种类型的值。此规则的主要兴趣是标量类型,如int
和float
。在您的特定情况下,很明显,通过更改结构的成员(unsigned char []
),您可以更改整个结构,反之亦然。
此案例由严格别名规则的第5个子案例涵盖。为了完整起见,我引用了整个部分:
6.5表达式,第7页
对象的存储值只能由具有其中一个的左值表达式访问 以下类型(此列表的目的是指定对象可能或可能没有别名的情况):
- 与对象的有效类型兼容的类型,
- 与对象的有效类型兼容的类型的限定版本
- 对应于有效类型的有符号或无符号类型 对象,
- 对应于合格版本的有符号或无符号类型的类型 有效的对象类型,
- 包含其中一种上述类型的聚合或联合类型 成员(包括,递归地,子集合或包含的联合的成员),或
- 字符类型
aggegate types 的定义在:
6.2.5类型,第21页
算术类型和指针类型统称为标量类型。数组和 结构类型统称为聚合类型。