首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >备忘录的实施

备忘录的实施
EN

Code Review用户
提问于 2017-09-06 09:59:40
回答 2查看 3.5K关注 0票数 12

这是我对memmove的实现;我可以在哪里改进呢?

代码语言:javascript
复制
void* memmove(void* dest, const void* src, std::size_t count)
{
    char *dest_ = static_cast<char*>(dest), *src_ = (char*)(src);
    if ((char*)src + count > dest && src < dest) //
    {
        dest_ += (src_ += count - 1, count - 1);
        while (count--) *dest_-- = *src_--;
    }
    else while (count--) *dest_++ = *src_++;
    return dest;
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2017-09-06 11:01:02

缺少标头:#include <cstddef>std::size_t所必需的(其他标头也提供它)。

src_没有必要抛弃*src的稳定性:

代码语言:javascript
复制
char *dest_ = static_cast<char*>(dest);
char const *src_ = static_cast<char const*>(src);

就我个人而言,我只想选择ds,而不是那些丑陋的下划线,但这在很大程度上是品味的问题。

在指向不同对象的指针之间使用<进行算术和比较是未指定的行为;我们可以安全地使用std::less。或者我们可以接受未指定的结果,因为在srcdest位于不同对象的情况下,使用哪个分支并不重要。

没有必要测试src + count > destsrc < dest;只要在分支中不减去count==0,我们就可以很高兴地为任何低到高的副本使用“反向”副本。

在“反向”分支中,将分配给src_的任务隐藏在分配给dest_的内部是不诚实的。写成两句话要清楚得多:

代码语言:javascript
复制
    src_ += count - 1;
    dest_ += count - 1;

我们可以避免-1,如果我们在减少之前,而不是后减少(它是安全的指向一个过了尾声)。

风格:在else的两边使用大括号,或者两者都不使用;避免使用if () {} else ;

我的版本

代码语言:javascript
复制
#include <cstddef>

void *memmove(void *dest, const void *src, std::size_t count)
{
    auto d = static_cast<char*>(dest);
    auto s = static_cast<char const*>(src);

    // If s and d are in distinct objects, the comparison is
    // unspecified behaviour, but either branch will work.
    if (s < d) {
        s += count;
        d += count;
        while (count--)
            *--d = *--s;
    } else {
        while (count--)
            *d++ = *s++;
    }

    return dest;
}

性能

一次复制一个字符将是一种“懒散”。真正的实现利用了处理器的本地传输大小、DMA硬件和可用的专用指令。这就是为什么它是一个标准的库函数而不是用户提供的。

票数 18
EN

Code Review用户

发布于 2017-09-06 10:45:16

将指针与无关对象有未指定的结果进行比较。

不要使用C风格的转换,也不要在任何地方一致使用它们.相反,使用static_cast<char*>(const_cast<void*>(src))

不要在单个语句(dest_ += ...)中使用多个赋值,特别是不要与逗号运算符结合使用。这只会让人感到困惑,对人类读者和编译器都没有帮助。

删除空注释。它没有任何用途。

与添加count - 1不同,您可以添加count并使用预减量。这是更清晰的代码,因为你周围没有魔法1。

条件下的强制转换可以由src_代替。

整个条件应该读取(src_ < dest_ && dest_ < src_ + count),以匹配测试之间的通用模式。

票数 9
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/174935

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档