代码之家  ›  专栏  ›  技术社区  ›  Dr.Knowitall

{}在这些C++函数中意味着什么?

c++
  •  0
  • Dr.Knowitall  · 技术社区  · 7 年前

    我试图解决C++中的一些问题,但我以前从未见过这个表达式。因为我不知道这个表达式叫什么,所以我不能用谷歌搜索它。

    int main() {
       int something=1;
    
       {
         assert(something);
       }
    
       // What is the purpose of these braces?
       // and what is it called?
       {
         assert(something != NULL);
       }
    
       return;
    }
    
    2 回复  |  直到 7 年前
        1
  •  7
  •   lisyarus    7 年前

    使用大括号可以创建一个新的 block scope .

    每次你写 if (...) { ... } while (...) { ... } ,的 { ... } 部分是一个新的范围。在内部创建的具有自动存储持续时间的所有对象(通常是变量,但不是动态分配的对象,例如通过 new )将在到达范围结束时销毁。一个没有任何 if ,请 while 如果你需要限制某个东西的生命周期,等等是有用的。例如:

    {
        std::vector<float> some_data = get_the_data();
        send_somewhere(some_data);
        send_somewhere_else(some_data);
    }
    

    在这里,到达后 } ,的 some_data 对象将被销毁,它分配的内存将被释放,而您 不能 忘记删除它,因为它的删除是由语言本身保证的。

    另一个常见的例子是互斥锁:

    // some preparation code
    {
        std::lock_guard<std::mutex> lock { my_lovely_mutex };
        some_shared_resource.modify();
    }
    // something that does not need the mutex to be locked
    

    在这里, lock_guard 在创建时锁定互斥体,在销毁时解锁,即使 modify() 引发异常。再一次,你 不能 忘记打开互斥锁(忘记这是一件非常危险的事情)。


    也就是说,我不知道为什么 assert 进入一个单独的范围-一个适当的 断言 无论是函数还是宏,通常都是一个独立的语句,不需要这种黑客。

    正如RemyLebeau所指出的,作者使用的断言宏可能不具备上述属性,并且在内部创建了变量,或者做了其他事情,从而污染了调用它的范围,因此禁止使用它两次。例如,如果声明(假设)为

    #define assert(x) bool b = (x); _internal_assert(b);
    

    那么做

    assert(x);
    assert(y);
    

    将触发编译错误,因为这将扩展到

    bool b = (x); _internal_assert(b);
    bool b = (y); _internal_assert(b);
    

    其中变量 b 声明两次。

    藏着这样一个 断言 在它自己的作用域中修复了这个问题,因为在不同作用域中声明的变量不会相互干扰:

    {
        bool b = (x); _internal_assert(b);
    }
    // ...
    {
        bool b = (y); _internal_assert(b);
    }
    
        2
  •  0
  •   Christopher Pisz    7 年前
    • 表示块的开始
    • }表示块的结尾

    阻止影响范围。 在您介绍的案例中,它们除了满足作者的风格之外,没有其他用途。