【问题标题】:Is returning void valid code?是否返回无效的有效代码?
【发布时间】:2010-08-01 17:49:40
【问题描述】:

我发现以下代码被 Visual C++ 2008 和 GCC 4.3 编译器接受:

void foo()
{

}

void bar()
{
  return foo();
}

我有点惊讶它可以编译。这是语言功能还是编译器中的错误? C/C++ 标准对此有何规定?

【问题讨论】:

    标签: c++ c


    【解决方案1】:

    这是 C++ 的语言特性

    C++ (ISO 14882:2003) 6.6.3/3

    具有“cv void”类型表达式的返回语句只能用于返回类型为 cv void 的函数;表达式在函数返回给它的调用者之前被计算。

    C (ISO 9899:1999) 6.8.6.4/1

    带有表达式的 return 语句不应出现在返回类型为 无效。

    【讨论】:

    • 请注意,许多可以同时编译 C 和 C++ 的编译器会在编译 C 代码时将 C++ 规则作为非标准扩展提供,但如果您想要可移植,则不应依赖此规则。
    【解决方案2】:

    是的,它是有效的代码。当您有模板函数时,这是必要的,以便您可以使用统一代码。例如,

    template<typename T, typename P>
    T f(int x, P y)
    {
      return g(x, y);
    }
    

    现在,g 可能会在第二个参数是某种特定类型时被重载以返回 void。如果“返回 void”无效,则对 f 的调用将中断。

    【讨论】:

    • T 不能为空,因为参数不能为空。
    • 谢谢,几分钟后我就意识到自己做了一个不好的例子。固定!
    • 这个特性也打开了一个小陷阱:在void positive_action(int n) { if (n&lt;0) return; action(n); [...] }中,如果action返回void,那么忘记return之后的分号不会给出错误或警告,但是action现在被调用n 是负数而不是正数。
    • 编译器也可以使用它作为他们应该进行尾调用优化的提示,如果经常调用f(),这可能很有用。
    【解决方案3】:

    这是有效的并且非常有用,例如在您想要在返回之前进行一些错误处理的情况下创建更清晰的代码:

    void ErrRet(int code, char* msg)
    {
       // code logging/handling error
    }
    void f()
    {
       if (...) return ErrRet(5, "Error Message !");
       // code continue
    }
    

    【讨论】:

      【解决方案4】:

      确实有效。我经常将它用于输入验证宏:

      #define ASSERT_AND_RETURN_IF_NULL(p,r) if (!p) { assert(p && "#p must not be null"); return r; }
      
      bool func1(void* p) {
        ASSERT_AND_RETURN_IF_NULL(p, false);
        ...
      }
      
      void func2(void* p) {
        ASSERT_AND_RETURN_IF_NULL(p, void());
        ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-19
        • 2010-10-15
        • 1970-01-01
        • 2012-07-01
        • 2014-04-30
        • 2020-04-25
        • 1970-01-01
        • 2017-05-16
        相关资源
        最近更新 更多