【问题标题】:Will statements after "return" keyword be executed?“return”关键字之后的语句会被执行吗?
【发布时间】:2014-04-16 06:58:19
【问题描述】:

我是 C++ 初学者,想知道这种情况的影响:

PCONSOLE_SCREEN_BUFFER_INFOEX GetConsoleInfo(void) {
    WaitForSingleObject(m_hSync);   // m_hSync is HANDLE to mutex created using CreateMutex()

    return m_pcsbi;    // m_pcsbi is of type PCONSOLE_SCREEN_BUFFER_INFOEX

    ReleaseMutex(m_hSync);      // <== will this line be executed?
}

想知道 [ReleaseMutex()] 会被执行吗?

【问题讨论】:

  • 你为什么不确定自己的测试程序?
  • 语句in if (0) { .. } 会被执行吗?以同样的方式,return 控制程序流程。 (MSVC++ 是否也对此发出警告?)
  • 无论您使用哪种编译器,都应该有一种方法可以激活警告;在这些警告中,应该有一个告诉您此代码将永远被执行。
  • 在现代 C++ 中,我们有一个 &lt;mutex&gt; 标头。它有一个漂亮的std::lock_guard,它会在作用域(包括函数作用域)的末尾自动解锁互斥锁

标签: c++ visual-c++ return


【解决方案1】:

在您的情况下,无法获取该代码。如果您有条件 return (例如 if (ptr==nullptr) return; ),那么当然有条件会跳过返回。但无条件返回将是最后执行的语句。

但是,RAII 样式清理确实发生在 return 之后。

【讨论】:

  • 对于 C++ 初学者,术语“RAII_style cleanup”可能有点不清楚,你不觉得吗? :)
  • @Spook True,但与此同时,它至少很容易被搜索到。
【解决方案2】:

在那个特定的场景中没有。您需要在离开函数之前释放互斥锁。

【讨论】:

    【解决方案3】:

    不,在 return 语句之后,作用域 Objects 的析构函数将被调用,程序将退出该函数。

    int main() { //Step 1
       GetConsoleInfo(); //2
    
       return (0); //6
    }
    
    PCONSOLE_SCREEN_BUFFER_INFOEX GetConsoleInfo(void) { //3
        WaitForSingleObject(m_hSync); //4
    
        return m_pcsbi; //5
    
        ReleaseMutex(m_hSync);
    }
    

    也许你应该这样做:

    int main() {
       WaitForSingleObject(m_hSync);
       GetConsoleInfo();
       ReleaseMutex(m_hSync);
       return (0);
    }
    
    PCONSOLE_SCREEN_BUFFER_INFOEX GetConsoleInfo(void) {
        return m_pcsbi;
    }
    

    【讨论】:

    • 什么都没有?析构函数在返回后被执行。这为语言增添了美感。
    • 非常感谢。您的回答帮助我了解这是如何执行的。 (尝试勾选这个答案,但不允许再过几分钟......)所以,为了释放互斥锁,我必须这样做吗?:WaitForSingleObject(m_hSync); PCONSOLE_SCREEN_BUFFER_INFOEX p = m_pcsbi; ReleaseMutex(m_hSync);返回 p;
    • 我正在考虑在我的函数中调用 Wait...() 函数,因为调用我的函数 (GetConsoleInfo()) 的人可能不知道其他线程可能正在更改控制台信息。 ..
    • @tongko:不幸的是,这还不够。仅当共享资源的两个用户也使用相同的互斥锁时,互斥锁才能保护共享资源。如果对方不知道你的代码在控制台信息上工作,它也不会知道你的控制台信息互斥体。
    【解决方案4】:

    不可以,但你可以有例外

    if 语句示例:

       PCONSOLE_SCREEN_BUFFER_INFOEX GetConsoleInfo(void) {
         WaitForSingleObject(m_hSync);   // m_hSync is HANDLE to mutex created using CreateMutex()
    
    
         //if(statement)
                return m_pcsbi;    // m_pcsbi is of type PCONSOLE_SCREEN_BUFFER_INFOEX
         //else
              ReleaseMutex(m_hSync);      // if the statement is false, it will skip return and execute this line
    }
    

    【讨论】:

      【解决方案5】:

      这正是需要RAII 的地方,由std::unique_lock 实现:

      PCONSOLE_SCREEN_BUFFER_INFOEX GetConsoleInfo()
      {
          static std::mutex m_hSync;
          std::unique_lock<std::mutex> lock{m_hSync};
      
          return m_pcsbi;    // m_pcsbi is of type PCONSOLE_SCREEN_BUFFER_INFOEX
      
          // mutex is released implicitly here
      }
      

      释放互斥锁应该在作用域结束时自动完成,包括抛出异常的情况(在stack unwinding 期间)。此时只能调用析构函数,std::unique_lock 的析构函数会准确释放互斥体。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        相关资源
        最近更新 更多