7 c void-pointers opaque-pointers
C99 - 特别是第6.2.6.1节第4段 - 规定允许将对象表示复制到unsigned char数组中:
struct {
int foo;
double bar;
} baz;
unsigned char bytes[sizeof baz];
// Do things with the baz structure.
memcpy(bytes, &baz, sizeof bytes);
// Do things with the bytes array.
Run Code Online (Sandbox Code Playgroud)
我的问题:我们不能通过简单的转换避免额外的内存分配和复制操作吗?例如:
struct {
int foo;
double bar;
} baz;
unsigned char *bytes = (void *)&baz;
// Do stuff with the baz structure.
// Do things with the bytes array.
Run Code Online (Sandbox Code Playgroud)
当然,需要跟踪大小,但这首先是合法的,还是属于实现定义或未定义行为的范围?
我问,因为我正在实现一个类似的算法qsort,我希望它适用于任何类型的数组,就像它qsort一样.
6.5表达式
[...]
6访问其存储值的对象的有效类型是对象的声明类型(如果有的话).87)如果通过具有类型的左值将值存储到没有声明类型的对象中如果不是字符类型,则左值的类型将成为该访问的对象的有效类型以及不修改存储值的后续访问.如果使用memcpy或memmove将值复制到没有声明类型的对象中,或者将其复制为字符类型数组,则该访问的修改对象的有效类型以及不修改该值的后续访问的有效类型是复制值的对象的有效类型(如果有).对于没有声明类型的对象的所有其他访问,对象的有效类型只是用于访问的左值的类型.
7 对象的存储值只能由具有以下类型之一的左值表达式访问:88)
- 与对象的有效类型兼容的类型,
- 与对象的有效类型兼容的类型的限定版本,
- 与对象的有效类型对应的有符号或无符号类型的类型,
- 与有效类型的对象的限定版本对应的有符号或无符号类型的类型,
- 聚合或联合类型,包括其成员中的上述类型之一(包括递归地,子聚合或包含联合的成员),或者
- 一个字符类型.
强调我的.因此,您可以将任何类型视为字符数组(unsigned char[],char[]或signed char[]).
我还引用了第6段,因为它反过来不适用.