“警告:并非所有控制路径都返回值”是什么意思? (C ++)

时间:2018-03-18 14:29:01

标签: c++

我得到的确切警告是

warning C4715: "spv::Builder::makeFpConstant": not all control paths return a value

spv::Builder::makeFpConstant

Id Builder::makeFpConstant(Id type, double d, bool specConstant)
{
        assert(isFloatType(type));

        switch (getScalarTypeWidth(type)) {
        case 16:
                return makeFloat16Constant(d, specConstant);
        case 32:
                return makeFloatConstant(d, specConstant);
        case 64:
                return makeDoubleConstant(d, specConstant);
        }

        assert(false);
}

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:2)

嗯,警告信息确切地说明了什么是错误的。

如果NDEBUG被定义(即assert被禁用)并且case都没有被采用,那么控件在任何{{1}之前到达函数的末尾语句(导致未定义的行为)。

答案 1 :(得分:2)

assert不算作一个控制流逻辑。它只是一个"记录"合同检查。在发布版本中,它甚至不会发生!它只是一个调试工具。

因此,如果标量类型宽度不是16,32或64,那么您将使用省略return语句的函数。这意味着您的程序具有未定义的行为。警告告诉您,您需要在所有案例中返回一些内容,即使您认为其他案例在运行时也不会发生。

在这种情况下,如果你越过switch而不返回,我可能会抛出异常 - 这可能会像其他任何例外情况一样处理。如果您不想要例外,另一种选择是自己调用std::terminate(这是断言最终将在调试版本中执行的操作)。

然而,终止是一个核选项,你真的不希望你的程序终止生产;你希望它通过你现有的异常处理渠道踢出正确的诊断信息,这样当你的客户报告错误时,他们可以说"显然makeFpConstant得到了一个它没有预料到的价值"你知道该怎么做如果您不想向客户泄露功能名称,那么您至少可以选择一些"秘密"只有您的团队/企业知道的故障代码(并在内部记录!)。

但是,在调试版本中终止通常很好,所以请保留assert!或者只是依靠你现在拥有的例外情况,如果你不抓住它就会导致终止。

以下我可能会写这个函数:

Id Builder::makeFpConstant(
   const Id type,
   const double d,
   const bool specConstant
)
{
   assert(isFloatType(type));

   const auto width = getScalarTypeWidth(type);
   switch (width) {
      case 16: return makeFloat16Constant(d, specConstant);
      case 32: return makeFloatConstant(d, specConstant);
      case 64: return makeDoubleConstant(d, specConstant);
   }

   // Shouldn't get here!
   throw std::logic_error(
      "Unexpected scalar type width "
      + std::to_string(width)
      + " in Builder::makeFpConstant"
   );
}