gpt4 book ai didi

c++ - 退出功能的可能性

转载 作者:行者123 更新时间:2023-11-30 21:38:12 25 4
gpt4 key购买 nike

我想知道 C/C++ 中的一般主题。假设我们正在执行一个调用函数 B() 的函数 A(),我们能否确定 A() 中对 B() 的调用将始终在调用本身“之后”返回。

在一个更一般的问题中,退出函数的可能性有哪些?

C 关键字是(维基百科):auto、break、case、char、const (C89)、 continue、default、do、double、else、enum (C89)、extern、float、for、goto、if、inline (C99)、int、long、register、restrict (C99)、return、short、signed (C89)、sizeof、static、struct、switch、typedef、union、unsigned、void (C89)、 volatile (C89)、while、 _ bool (C99)、_复数 (C99)、_虚数 (C99)。

据我所知,这个主题中有趣的是:

  • break/continue :在循环或开关中使用(正如 GCC 在尝试后告诉我的那样),它们无法退出函数。
  • goto:标签的范围受函数限制,因此 goto 无法退出函数
  • return :可以退出函数,但始终返回到调用后的指令。有了这个我们就放心了。
  • exit()/abort() 函数将结束应用程序。我们不会返回调用点,但是..我们根本不会返回。

我认为这是针对C语言的。您认为还有另一种方法可以退出函数而不返回到调用点吗?

<小时/>

在C++中,异常显然不会返回到调用点。它们要么进入 catch block ,要么到达调用函数,寻找 catch block 。

据我所知,这是唯一的情况。

谢谢你帮助我=)

最佳答案

在标准 C(使用 setjmp/longjmp)和 C++(使用异常)中,可以有效地返回到更接近 CFG 根的标记点。实际上,函数可能永远不会返回,但如果它确实返回,它将到达调用之后的位置。

但是,setjmp 机制的低级性质实际上使得实现协程成为可能(尽管以不可移植的方式)。 Posix 试图通过强制 makecontext 和 friend 来改善这种情况,这些函数允许显式堆栈交换,但这些函数在 Posix.1-2001 中已被弃用,并从 Posix.1-2008 中删除,理由是可移植性问题,建议改用线程。尽管如此,仍有许多协程库正在使用,它们利用这些功能让 C 程序员享受协程的灵 active 。

在协程控制流中,虽然(协同)调用之后的执行路径可能是蜿蜒的,但函数调用仍然是永远不会返回或最终返回到紧随其后的点。然而,C 库设施的低级性质使得实现更复杂的控制流成为可能,其中给定的(共同)调用可能会返回多次。 (我从未在生产代码中见过这种特殊的异常情况,但我不能声称见过世界上所有生产代码的一小部分:))。

C 的 gcc 扩展允许使用“标签值”,它们是指向代码中标签的指针。这些是实值(类型为 void *),因此它们可以作为参数传递给函数。 (gcc 手册警告不要这样做。)通过一些逆向工程,可能可以编写一个函数,该函数接受一个或多个标签参数并使用其中一个作为返回点。这显然是对该功能的滥用,可能既不便携也不面向 future ,而且几乎肯定会破坏现有的任何编码标准。

与实际上是核心语言一部分的 C++ 异常相反,C 库设施的有趣之处在于它们实际上是函数;在 C 中,与许多编程语言一样,可以通过函数指针间接调用函数,因此可能无法通过静态分析轻松计算在给定调用点调用哪个函数。所以,至少在理论上,我想说所有的赌注都没有了。但实际上,一个安全的假设是函数调用最终要么返回到下一个点,要么返回到调用堆栈的某个位置,可能是操作系统环境。

关于c++ - 退出功能的可能性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17656252/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com