假设我正在制作一个应用程序,它将持续很长时间,并且不会因为任何正常原因而终止(例如,用户终止应用程序,e.x: HTTP服务器)。
我标记main本身具有C++11标准属性[[noreturn]]指示它决不能在不中止或引发异常的情况下将控制返回给被调用者。
[[noreturn]] int main(
int const argc,
char const * const[] argv
) { ... }我首先解析CLI参数,然后将提取的数据传递到“真正的”main函数中,在那里继续执行更多的工作。
另一个函数,我们将调用它realMain,也被标记为[[noreturn]]..。
在我的代码中,我给出了main将返回语句函数realMain,并立即收到有关从noreturn函数返回的通用Clang警告。
[[noreturn]] int realMain(Data const data) {
...
std::cerr << "Unreachable!" << std::endl;
std::abort();
}
[[noreturn]] int main(...) {
...
auto const parsed_cli_args = parse(argv, argc);
...
return realMain(parsed_cli_args);
}返回到其他noreturn函数是否安全,或者这是未定义的行为?
(与此无关,任何编译器可以利用这一点吗?例如制作main
直接使用jmp而不是调用realMain?)
发布于 2021-03-01 07:27:04
返回到其他noreturn函数是否安全,或者这是未定义的行为?
我想知道这里是否有一些语言混乱。
我不确定你是不是指UB main()使用假设的返回值从realMain()
这是它永远不应该得到的;或者如果它是UB realMain()
返回到main()..。
无论如何,基于cppreference首选项凯西链接到:
void q [[ noreturn ]] (int i) {
// behavior is undefined if called with an argument <= 0
if (i > 0) {
throw "positive";
}
}我能理解仅仅是拥有它return realMain(); 在
main()不是UB。只是UB if realMain()
再也不会回来了。在这一点上,无论是什么都无关紧要main()
是的,它已经是UB了,因为realMain()先打破了“不退货”的承诺。
但既然这两个都不会回来,我不明白你为什么要写return
在任何情况下,而不是例如将调用留给realMain()
作为的最后一条语句main(),不返回。
发布于 2021-03-01 06:37:06
这是未定义的行为。如C++标准中所指定的:
9.12.9 Noreturn属性 dcl.attr.noreturn
如果函数f被调用,其中f之前是用noreturn属性声明的,并且f最终返回,则行为是未定义的。
函数是否通过返回另一个函数的结果来返回[[noreturn]]-attributed函数是无关紧要的。
发布于 2021-03-01 06:36:21
是的。
(强调我的)
解释
指示函数不返回。
此属性仅适用于在函数声明中声明的函数的名称。
如果具有此属性的函数实际返回,则行为未定义。
如果有任何声明指定了此属性,则函数的第一个声明必须指定此属性。如果函数是用[不返回]在一个翻译单元中,并且声明相同的函数时不使用[不返回]在另一个翻译单元中,程序格式错误;不需要诊断。
https://stackoverflow.com/questions/66414510
复制相似问题