从 noreturn 函数返回未定义的行为,如果它 returns 调用另一个 noreturn 函数?
Is returning from a noreturn function undefined behavior, if it returns with a call to another noreturn function?
假设我正在制作一个将持续很长时间的应用程序,并且预计不会因任何正常原因而终止(例如,用户终止应用程序,e.x:一个 HTTP 服务器)。
我用 C++11 标准属性 [[noreturn]]
标记 main
本身,表明它绝不能 return 在不中止或抛出异常的情况下将控制权返回给被调用者。
[[noreturn]] int main(
int const argc,
char const * const[] argv
) { ... }
我从解析 CLI 参数开始,然后将提取的数据传递到我的“真实”主函数中,更多的工作将在该函数中继续进行。
另一个函数,我们称之为 realMain
,也被标记为 [[noreturn]]
。
在我的代码中,我给 main
函数一个 return 语句到 realMain
,并立即收到关于 returning 的通用 Clang 警告来自 noreturn函数。
[[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);
}
return进入其他没有return的函数是否安全,或者这是未定义的行为?
(无关紧要,任何编译器都可以利用这一点吗?例如,使 main
直接跳转而不是调用 realMain
?)
(强调我的)
Explanation
Indicates that the function does not return.
This attribute applies to the name of the function being declared in function declarations only. The behavior is undefined if the function with this attribute actually returns.
The first declaration of the function must specify this attribute if any declaration specifies it. If a function is declared with [[noreturn]] in one translation unit, and the same function is declared without [[noreturn]] in another translation unit, the program is ill-formed; no diagnostic required.
这是未定义的行为。按照 C++ 标准的规定:
9.12.9 Noreturn attribute [dcl.attr.noreturn]
If a function f is called where f was previously declared with the
noreturn attribute and f eventually returns, the behavior is
undefined.
函数 returns 是否通过返回另一个 [[noreturn]]
属性函数的结果并不重要。
Is it safe to return into other noreturn functions, or is this undefined behavior?
我想知道这里是否有一些语言混淆。
我不确定你的意思是不是 main()
到 return 的 UB 使用 realMain()
的假设 return 值,它永远不会得到;或者如果它是 realMain()
到 return 回到 main()
.
的 UB
无论如何,基于 Casey 链接到的 cppreference 上的示例:
void q [[ noreturn ]] (int i) {
// behavior is undefined if called with an argument <= 0
if (i > 0) {
throw "positive";
}
}
我会明白,仅仅 return realMain();
在 main()
中并不是 UB。如果 realMain()
实际上 return 就是 UB。到那时,main()
做什么并不重要,因为 realMain()
首先打破了“不return”的承诺。
但是因为两者都不应该 return,我不明白为什么你无论如何都要写 return
,而不是例如只是将对 realMain()
的调用作为 main()
的最后一条语句,没有 return.
假设我正在制作一个将持续很长时间的应用程序,并且预计不会因任何正常原因而终止(例如,用户终止应用程序,e.x:一个 HTTP 服务器)。
我用 C++11 标准属性 [[noreturn]]
标记 main
本身,表明它绝不能 return 在不中止或抛出异常的情况下将控制权返回给被调用者。
[[noreturn]] int main(
int const argc,
char const * const[] argv
) { ... }
我从解析 CLI 参数开始,然后将提取的数据传递到我的“真实”主函数中,更多的工作将在该函数中继续进行。
另一个函数,我们称之为 realMain
,也被标记为 [[noreturn]]
。
在我的代码中,我给 main
函数一个 return 语句到 realMain
,并立即收到关于 returning 的通用 Clang 警告来自 noreturn函数。
[[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);
}
return进入其他没有return的函数是否安全,或者这是未定义的行为?
(无关紧要,任何编译器都可以利用这一点吗?例如,使 main
直接跳转而不是调用 realMain
?)
(强调我的)
Explanation
Indicates that the function does not return.
This attribute applies to the name of the function being declared in function declarations only. The behavior is undefined if the function with this attribute actually returns.
The first declaration of the function must specify this attribute if any declaration specifies it. If a function is declared with [[noreturn]] in one translation unit, and the same function is declared without [[noreturn]] in another translation unit, the program is ill-formed; no diagnostic required.
这是未定义的行为。按照 C++ 标准的规定:
9.12.9 Noreturn attribute [dcl.attr.noreturn]
If a function f is called where f was previously declared with the noreturn attribute and f eventually returns, the behavior is undefined.
函数 returns 是否通过返回另一个 [[noreturn]]
属性函数的结果并不重要。
Is it safe to return into other noreturn functions, or is this undefined behavior?
我想知道这里是否有一些语言混淆。
我不确定你的意思是不是 main()
到 return 的 UB 使用 realMain()
的假设 return 值,它永远不会得到;或者如果它是 realMain()
到 return 回到 main()
.
无论如何,基于 Casey 链接到的 cppreference 上的示例:
void q [[ noreturn ]] (int i) {
// behavior is undefined if called with an argument <= 0
if (i > 0) {
throw "positive";
}
}
我会明白,仅仅 return realMain();
在 main()
中并不是 UB。如果 realMain()
实际上 return 就是 UB。到那时,main()
做什么并不重要,因为 realMain()
首先打破了“不return”的承诺。
但是因为两者都不应该 return,我不明白为什么你无论如何都要写 return
,而不是例如只是将对 realMain()
的调用作为 main()
的最后一条语句,没有 return.