8

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

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

可以变成(不打IDE自动缩进):

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

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

4

3 回答 3

12

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

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

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

...

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

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

于 2013-10-13T21:57:57.903 回答
10

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

于 2013-10-13T20:18:32.203 回答
3

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

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

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

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

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

于 2013-10-14T13:23:19.717 回答