【问题标题】:C++, recreate memset with pointers and address of operatorsC ++,使用指针和运算符地址重新创建memset
【发布时间】:2019-08-09 12:11:18
【问题描述】:

tl;dr;如何用基本的c++重现memset

我试图弄清楚memset 是如何工作的,并看看我是否可以使用指针和地址在正常的c++ 中重现它。

这是我到目前为止所得到的。

    void test_memset( void * origin, uint8_t val, size_t size ){
         if( size != 1 ){
             uint8_t* new_or = (uint8_t*) origin;  // casting to uint8_t*
             *new_or ^= (*new_or & 0xff); // clearing any remaining data
             *new_or ^= val;              // assigning the val
             new_or++;                    // incrementing pointer
             test_memset_alloc( new_or, val, size-1 ); // recursion
         }
    }   

所以问题是:memset 在基本 c++ 中是什么样子的?

编辑 1:

以类似的方式回答here,而here 则稍微冗长一些。这两个答案都比我的提议更适合。

但我希望看到一些详细的解决方案,这将能够解释 Mort(业务线开发人员)或知识不完整的人,比:“这令人不悦”更清楚地解释正在发生的事情或“不是 C++ 方式”。

【问题讨论】:

  • 因为递归限制?
  • @Danilo memset 在 C++ 代码中实现看起来很像 stackoverflow.com/a/18851921/126769 ,如果你引入了无意义的代码(在某些情况下它甚至是未定义的行为,因为你可以读取一个未初始化的值)比如*new_or ^= (*new_or & 0xff); ,您几乎可以保证混淆“用户”而不是教他们一些东西。

标签: c++11 memset


【解决方案1】:

C 或 C++ 中的基本、低效但正确的 memset 实现如下所示:

typedef unsigned char byte;

void* memset(void* s, int c, size_t sz) {
    byte* p = (byte*)s;

    while (sz--)
        *p++ = (byte)c;
    return s;
}

这使用了循环,因为循环是完成这项工作的正确工具。你坚持避免循环是没有意义的。 “从处理器的角度来看,它们不存在”不是避免它们的正当理由。这不是一个真正的陈述,甚至不是一个有意义的陈述。您的进一步解释暴露了对 How Things Work™ 的严重缺乏了解。如果一个循环是一个黑盒,那么 everything 就是一个黑盒。函数调用是一个黑盒子。演员表是一个黑匣子。 if 语句是一个黑匣子。像(x+y)*z 这样的算术表达式是一个黑盒子。这些都不比循环更透明。

【讨论】:

    【解决方案2】:

    memset 在基本 C++ 中看起来像以下内容:memset

    不开玩笑。这是一个非常基本的功能,对于编译器来说,下一步可能是针对特定目标的汇编代码。

    【讨论】:

    • 我希望你明白,事物的定义并不是名称本身。这个问题并不是为了证明或替换当前功能。问题是作为对 memset 进一步理解的发展。如果有人试图重构一个函数,那么他/她可以更好地理解编译器出错时的消息意味着什么。我强烈建议您是否可以在问题中包含更多信息。
    • @Danilo:这就是为什么我说 在基本 C++ 中。在 C++ 中你不能比memset 更进一步。除此之外,还有两个方向。您可以查看指定英语行为的 C 标准(C++ 继承自 C),或者查看生成的汇编指令。
    • 好吧,我明白了……我真的明白了。但你必须明白,“将 ptr 指向的内存块的前 num 字节设置为指定值(解释为无符号字符)” 实际上并没有显示它是如何工作的。而当编译器在示例中返回错误时,用户会目瞪口呆。这就是为什么我选择“如果有人试图重构一个函数,那么他/她可以更好地理解编译器出错时的消息意味着什么。”
    • @Danilo:当然,C 标准并没有直接定义如何它的工作原理。这不是 C 标准的重点。 C 标准描述了不同实现的共同点。确切的实施细节有所不同。这就是为什么我说另一个方向是查看特定编译器生成的程序集。
    • 所以,请花点时间...在它的汇编代码和 c++ 代码之间建立关联。解释它,以便 newb 可以理解它,以便我可以接受所有新用户的答案。让我们努力吧!让我们以新用户无需再学习 3 种语言即可理解编译器错误的方式来解释这一点。来吧,这就像你的时间 5 到 10 分钟。
    猜你喜欢
    • 1970-01-01
    • 2021-07-02
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多