7

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.

我的问题:我们不能通过简单的转换来避免额外的内存分配和复制操作吗?例如:

struct {
    int foo;
    double bar;
} baz;
unsigned char *bytes = (void *)&baz;

// Do stuff with the baz structure.

// Do things with the bytes array.

当然,需要跟踪大小,但这首先是合法的,还是属于实现定义或未定义行为的领域?

我问是因为我正在实现一个类似于 的算法qsort,并且我希望它适用于任何类型的数组,就像它qsort一样。

4

1 回答 1

6

6.5 表达式

[...]
6 访问其存储值的对象的有效类型是对象的声明类型,如果有的话。87) 如果一个值通过具有非字符类型的左值存储到没有声明类型的对象中类型,则左值的类型成为该访问和不修改存储值的后续访问的对象的有效类型。如果使用 memcpy 或 memmove 将值复制到没有声明类型的对象中,或者复制为字符类型的数组,则对于该访问和不修改该值的后续访问,修改对象的有效类型是从中复制值的对象的有效类型(如果有的话)。对于没有声明类型的对象的所有其他访问,
7对象的存储值只能由具有以下类型之一的左值表达式访问:88)

  • 与对象的有效类型兼容的类型,
  • 与对象的有效类型兼容的类型的限定版本,
  • 与对象的有效类型相对应的有符号或无符号类型,
  • 对应于对象有效类型的限定版本的有符号或无符号类型,
  • 聚合或联合类型,在其成员中包括上述类型之一(递归地包括子聚合或包含联合的成员),或
  • 一个字符类型

强调我的。因此,您可以将任何类型视为字符数组(unsigned char[],char[]signed char[])。

我还引用了第 6 段,因为它使相反的情况不适用。

于 2014-07-13T21:22:51.990 回答