为什么下面的函数中 char* 和 void* 需要相同的对象表示和对齐要求?

问题描述 投票:0回答:1

昨天提出的问题的答案让我产生了新的疑问。 C99官方原理文档中有这么一句话:

指向 void 的指针必须与指向 char 的指针具有相同的表示和对齐方式;该规则的目的是允许调用 memcpy 和 free 等库函数的现有程序继续工作。

据我所知,官方 C99 基本原理文件阐述了该条款的意图和历史背景。观察到 C89 中添加了类型

void

void *
。在此之前,传统上使用 
char *
 类型作为 
void *
 现在专门服务的指针角色,并且相应地编写了标准库函数(以及许多其他函数)。
我了解到的另一条可能有用的信息是,在旧式 K&R 风格的函数声明中,没有函数原型。
对于传递给没有范围内原型的函数的指针值,不会进行自动转换。

我在C89中看到

memcpy

已经有了函数原型
void *memcpy (void *s1, const void *s2, size_t n);

在C89之前,

char*

被用作通用指针类型,所以无论过去还是现在,任何类型都可以作为
memcpy
的参数,
memcpy
都可以正常调用。在C89之后,
void*
被用作通用指针类型,并且
memcpy
具有函数原型。现在任何类型都可以作为
memcpy
的实参(实参的类型会转换为形参的类型),也可以正常调用了。我不明白为什么 
void*
 需要与 
char*
 具有相同的表示和对齐要求。

换句话说,即使

char*

void*
没有相同的对象表示和对齐要求,无论是过去还是现在,我都找不到任何调用
memcpy
可能违反标准的地方。

那么上面这句话是什么意思呢?有谁能来救救我吗?

感谢您的阅读。

c c11
1个回答
0
投票
在没有字节寻址的古代硬件上,

char*

可能比
int*
更大。额外的大小用于“部分单词”信息,以从多字符单词中选择单个字符。

规则就是在这样的机器上,

void*

也必须有这个额外的空间,这样它就可以存储
char*

在所有其他类型的硬件上,该规则没有任何意义。

© www.soinside.com 2019 - 2024. All rights reserved.