c++ 块 { } 是否有负面影响

Do c++ blocks { } have a negative impact

本文关键字:影响 是否 c++      更新时间:2023-10-16

我最近发现{}块可以单独使用。对我来说,在某些情况下,这确实有助于可读性例如,在以下代码中:

push();
foo();
push();
foo();
foo();
pop();
pop();

可以成为(无需对抗 IDE 自动缩进):

push();
{
    foo();
    push();
    {
        foo();
        foo();
    }
    pop();
}
pop();

除了对样式的主观意见之外,这是否有任何负面影响(例如编译器的优化较少,它们有其他用途等),或者这些是否可以安全使用。

当它们不更改代码的含义时(如您的示例所示),它们没有理由对优化产生任何影响。如果他们这样做,那么这是特定编译器的怪癖。

要强制您的pop()调用映射您的push()呼叫,您甚至可以这样做:

struct Pusher {
    Pusher() { push(); }
    ~Pusher() { pop(); }
};

{
    Pusher p1;
    foo();
    {
        Pusher p2;
        foo();
        foo();
    }
}

该模式通常称为 RAII。不过,它确实改变了代码的含义——在我的代码中,如果对foo()的调用之一引发异常,pop()将被调用,而在您的代码中则不会。在大多数(但不是全部)情况下,您需要在返回之前撤消某些操作,您还需要在异常时撤消。

关于你的第二个例子的一切都是 100% 好的。 额外的块可能会影响其中声明的变量的范围,但您没有这样做。

创建这样的块会创建新的作用域。因此,您将在进入和退出这些范围时运行构造函数和析构函数。您还将有更多机会让名字相互隐藏。它们可以安全使用,但您必须牢记这些事项。

顺便说一句,这是主观的,但我不认为您对范围的使用有助于提高可读性。您可以使用空行完成同样的事情。如果我在评论中看到您的代码,我会问自己为什么要创建这样的范围。

作用域有用的一件事是结合 RAII 样式编程来控制生命周期。在此示例中,作用域用于限制持有互斥锁的时间量。

int a = b + c;
{
   OS::Mutex::Lock lock(mutex);
   some_shared_variable = a;
}

这里Lock是一个 RAII 样式类,它在构造函数中获取互斥锁并在析构函数中释放它。通过显式使用作用域,可以限制锁定的持有时间。