问题
In the following setup
typedef struct {
unsigned char data[64];
} mystruct;
int myfunc(mystruct* arg); // fills arg with data
is it safe to call myfunc
with a pointer to a 64 byte array? E.g.
unsigned char buffer[64];
myfunc((mystruct*) buffer)
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);
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.
回答1:
Technically it works and you can use it. As pointed in comments the relevant part of the ANSI standard is:
6.7.2.1: Structure and union specifiers
... 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.
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.
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 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
— a character type
where the definition of aggegate types is in:
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.
来源:https://stackoverflow.com/questions/49063595/is-it-safe-to-cast-an-array-to-a-struct-with-one-array-as-member