首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C/C++ (ringBuffer指针)中变量的重新设置/封装

C/C++ (ringBuffer指针)中变量的重新设置/封装
EN

Stack Overflow用户
提问于 2019-07-11 12:59:29
回答 2查看 62关注 0票数 0

我正在编写一些环形缓冲器,这个问题问了我好几次。

苏普豪斯,我们有一个计数器,我们需要在一定数量后重新设置。我已经看到了几个环形缓冲区的例子(主要是音频,围绕r/w指针进行包装),它们可以做到这一点:

代码语言:javascript
复制
x++;
if (x  == SOME_NUMBER ){ // Reseting counter
    x -= x;
}

在这样做时是否有任何区别/偏好:

代码语言:javascript
复制
x++;
if (x  == SOME_NUMBER ){ // Reseting counter
    x = 0;
}

这个问题适用于几乎所有类型的变量重置。在我的情况下,除了响蜂鸣器,我也重新设置一个计数器,做一个平均,所以我做了我的所有措施,我重新设置了计数器。

除了结果可能是相同的(x重新计算为零)之外,一种方法和另一种方法可能有一些不同。有什么偏好吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-11 14:38:11

考虑一下那些稍微修改过的片段版本。

代码语言:javascript
复制
void f(int n)
{
    int x = 0;
    for (;;)
    {
        ++x;
        if (x == n ) {   // Reseting counter
            x -= x;
        }
        // Ending condition to avoid UB
        if ( x == 42 )
            return;
    }
}

void g(int n)
{
    int x = 0;
    for (;;)
    {
        ++x;
        if (x == n ) {
            x = 0;
        }

        if ( x == 42 )
            return;
    }
}

如果您查看生成的程序集(例如使用编译器资源管理器),您将注意到现代优化编译器如何利用以此类推

Clang (使用-O2)为这两个函数生成相同的机器代码。它用

代码语言:javascript
复制
xor     eax, eax

将零加载到寄存器中,然后

代码语言:javascript
复制
cmove   ecx, eax

在需要时“重置”另一个寄存器。

Gcc只是创建了f(),然后g()变成了

代码语言:javascript
复制
jmp     f(int)

那就说

有什么偏好吗?

一个常见的指导方针是编写更易读和更易于维护的代码,并在对其进行分析之后才探索可能的优化。

在大多数情况下,我会使用x = 0;版本,因为它更好地传达了意图,IMHO。我只能想到采用x -= x;的几个理由:

  • 它不依赖“神奇的数字”。但是,在我的代码片段中,42文本就是这样的,0是一个例外情况。
  • 它不需要任何隐式转换。考虑x不是int的任何情况。
  • 在某些体系结构/工具链中,它实际上交付了更快的代码。我想不出任何东西,但那是无关紧要的。
票数 1
EN

Stack Overflow用户

发布于 2019-07-11 13:20:09

不同之处在于操作的数量:x -= x是减法和赋值,而x = 0只是赋值。除了CPU周期的数量之外,如果可以从其他线程访问x,则会影响行为。

一个简单的任务x = 0也要清楚得多。

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

https://stackoverflow.com/questions/56989823

复制
相关文章

相似问题

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