在标准C中从头开始实施memcpy在技术上是不可能的吗? [英] Is it technically impossible to implement memcpy from scratch in Standard C?

查看:56
本文介绍了在标准C中从头开始实施memcpy在技术上是不可能的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Howard Chu 写道:

Howard Chu writes:

在最新的C规范中,不可能编写malloc或memcpy的合法"实现.

In the latest C spec it is impossible to write a "legal" implementation of malloc or memcpy.

这是对的吗?我的印象是,在过去,该标准(至少)的意图是这样的事情会起作用:

Is this right? My impression is that in the past, the intent (at least) of the standard was that something like this would work:

void * memcpy(void * restrict destination, const void * restrict source, size_t nbytes)
{
    size_t i;
    unsigned char *dst = (unsigned char *) destination;
    const unsigned char *src = (const unsigned char *) source;

    for (i = 0; i < nbytes; i++)
        dst[i] = src[i];
    return destination;
}

这里违反了最新C标准中的哪些规则?或者, memcpy 规范的哪一部分没有被该代码正确实现?

What rules in the latest C standard are violated here? Or, what part of the specification of memcpy is not correctly implemented by this code?

推荐答案

对于 malloc 函数,第6.5§6段清楚地表明,不可能编写一致且可移植的C实现:

For the malloc function, paragraph 6.5 §6 makes it clear that it is not possible to write a conformant and portable C implementation :

访问其存储值的对象的有效类型是声明的类型.对象,如果有的话(87) ...

(非规范性)注释87说:

The (non normative) note 87 says:

已分配的对象没有声明的类型.

Allocated objects have no declared type.

声明没有声明类型的对象的唯一方法是...通过分配函数返回该对象!因此,在分配函数内部,您必须具有某物,这是标准所不允许的,以设置没有声明类型的存储区.

The only way to declare a object with no declared type is... through the allocation function which is required to return such an object! So inside the allocation function, you must have something that cannot be allowed by the standard to setup a memory zone with no declared type.

在常见的实现中,标准库malloc和free确实是用C实现的,但是系统知道这一点,并假定在 malloc 内部提供的字符数组只是没有声明的类型.句号.

In common implementations, the standard library malloc and free are indeed implemented in C, but the system knows about it and assumes that the character array which has been provided inside malloc just has no declared type. Full stop.

但是同一段的其余部分说明,编写 memcpy 实现(强调我的想法)并没有真正的问题:

But the remaining part of the same paragraph explains that there is no real problem in writing a memcpy implementation (emphasize mine):

...如果通过一个值将一个值存储到一个没有声明类型的对象中具有非字符类型的左值,则左值的类型变为该访问以及未修改的后续访问的对象的有效类型储值.如果将值复制到没有声明类型的对象中,则使用memcpy或memmove或复制为字符类型数组,然后是有效类型该访问以及未修改该对象的后续访问的已修改对象的value是从中复制值的对象的有效类型(如果有).为了对没有声明类型的对象的所有其他访问,则该对象的有效类型为只是用于访问的左值的类型.

... If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.

假设您将对象复制为字符类型的数组,这是严格的别名规则所允许的特殊访问,实现 memcpy 不会出现问题,并且您的代码是可行且有效的实施.

Provided you copy the object as an array of character type, which is a special access allowed per the strict aliasing rule, there is no problem in implementing memcpy, and your code is a possible and valid implementation.

恕我直言,霍华德·朱的咆哮是关于旧的良好的 memcpy 用法,该用法不再有效(假设 sizeof(float)== sizeof(int)):

IMHO the rant of Howard Chu is about that old good memcpy usage, which is no longer valid (assuming sizeof(float) == sizeof(int)):

float f = 1.0;
int i;
memcpy(&i, &f, sizeof(int));         // valid: copy at byte level, but the value of i is undefined
print("Repr of %f is %x\n", i, i);   // UB: i cannot be accessed as a float

这篇关于在标准C中从头开始实施memcpy在技术上是不可能的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆