首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在没有警告的情况下启用“丢失的返回语句”活动错误?

如何在没有警告的情况下启用“丢失的返回语句”活动错误?
EN

Stack Overflow用户
提问于 2022-05-11 10:57:47
回答 2查看 125关注 0票数 1

假设我有constexpr数据集。我主要在编译时使用它,它存储可能影响未来constexpr语句的设置的数据。string_view允许我命名这些设置并轻松地搜索它们:

代码语言:javascript
运行
复制
struct data {
    std::string_view name;
    int value;
};

constexpr auto data_set = std::array{
    data{"foo", 100},
    data{"bar", 200},
};

这是一个constexpr函数,它允许我找到数据点并返回它们的值:

代码语言:javascript
运行
复制
constexpr int get_data(std::string_view search) {
    for (auto& data : data_set) {
        if (data.name == search) {
            return data.value;
        }
    }
}

当我用正确的字符串名和不正确的字符串名称调用这个函数时,这种方法工作得很好。因为如果它找不到name,则该函数没有返回语句,因此无法初始化constexpr值:

代码语言:javascript
运行
复制
int main() {
    constexpr auto foo = get_data("foo");
    constexpr auto foo2 = get_data("foo2"); //Error C2131: expression did not evaluate to a constant
}

我的IDE (Visual )甚至给了我一个很好的可见活动错误:

代码语言:javascript
运行
复制
Error (active)  E0028   expression must have a constant value

但是,在使用此命令并对其进行非参数调用时,我总是会收到警告。

代码语言:javascript
运行
复制
warning C4715: 'get_data': not all control paths return a value

显然,我不能添加一个默认的返回值,因为这不符合"constexpr fails (如果无效)“的目的,但我仍然希望能够用它初始化运行时变量(因为在编译时仍然知道搜索string_view,这样做是安全的)。

那么,是否有一种方法可以对无效输入保留此错误,但删除该错误?你也能让这个函数不返回任何东西吗?

EN

回答 2

Stack Overflow用户

发布于 2022-05-11 10:57:47

consteval将启用此行为。因此,任何以这种方式标记的函数都必须在编译时进行计算。这也将删除警告,因为如果它没有正确计算,它将被错误所取代。

代码语言:javascript
运行
复制
consteval int get_data(std::string_view search) {
    for (auto& data : data_set) {
        if (data.name == search) {
            return data.value;
        }
    }
}
int main() {
    constexpr auto foo = get_data("foo");
    constexpr auto foo2 = get_data("foo2");
}

"foo2"行导致C2131和active error E3133:

代码语言:javascript
运行
复制
Error   C2131   expression did not evaluate to a constant
Error (active)  E3133   call to consteval function "get_data" did not produce a valid constant expression   

您仍然可以使用它初始化运行时变量:

代码语言:javascript
运行
复制
auto bar = get_data("bar");

因为get_data可以在编译时被计算,并且基本上被data{ "bar", 200 }.value;所取代,或者只是200

现在,consteval将使纯运行时调用不再工作(比如从std::cin输入或文件中读取搜索项),但这是所需的行为,因为理论上,如果输入无效,则可能导致未指定的分支。

,您也可以让这个函数不返回任何东西吗?

如果到达,可以在应该失败的分支中添加无效的语句。例如,1 / 0

代码语言:javascript
运行
复制
consteval void check_data(std::string_view search) {
    for (auto& data : data_set) {
        if (data.name == search) {
            return;
        }
    }
    auto invalid = 1 / 0;
}

int main() {
    check_data("foo");
    check_data("bar");
    check_data("bar2"); //E3133 active error
}

@GoswinvonBrederlow建议抛出异常,这也非常有效,甚至比1 / 0更干净,在我看来:

代码语言:javascript
运行
复制
consteval auto get_data(std::string_view search) {
    for (auto& data : data_set) {
        if (data.name == search) {
            return data.value;
        }
    }
    throw std::exception("fail");
}
consteval void check_data(std::string_view search) {
    for (auto& data : data_set) {
        if (data.name == search) {
            return;
        }
    }
    throw std::exception("fail");
}
int main() {
    constexpr auto foo = get_data("foo");
    constexpr auto foo2 = get_data("foo2"); //E3133 active error
    auto bar2 = get_data("foo2");  //E3133 active error

    check_data("foo");
    check_data("foo2"); //E3133 active error
}
票数 2
EN

Stack Overflow用户

发布于 2022-05-11 11:19:51

我知道可以有许多优雅的解决方案,但我建议的只是在函数的末尾添加一个无条件的返回。

代码语言:javascript
运行
复制
constexpr int get_data(std::string_view search) {
    for (auto& data : data_set) {
        if (data.name == search) {
            return data.value;
        }
    }
    return -1;
}

看到它在运行:https://godbolt.org/z/zKx7M3j8a

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72199810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档