我得到的确切警告是
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);
}
任何人都可以帮助我吗?
答案 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"
);
}