【问题标题】:Why do I see THROW in a C library?为什么我在 C 库中看到 THROW?
【发布时间】:2010-03-21 08:16:38
【问题描述】:

当我这样做时: less /usr/include/stdio.h(这只是一个 C 库 - 与 C++ 无关)

我在很多函数声明之后看到__THROW。 另外,上面几个函数的cmets说'这个函数是一个可能的取消点,因此没有标记__THROW' 这一切是为了什么?

throw 是用来处理异常的……但据我所知,C 并没有为它提供任何支持。

请解释一下。

【问题讨论】:

  • 哪个编译器?对我来说看起来像 GCC。 (请记住,没有“标准库”,因此指定您使用的实现会很有帮助。)
  • 啊,我知道你发现了 glibc :)

标签: c++ c exception header-files


【解决方案1】:

该头文件可能在该供应商的 C 和 C++ 编译器之间共享。你看看__THROW 的定义是什么?

我怀疑类似于:

#ifdef __cplusplus
    #define __THROW throw()
#else
    #define __THROW
#endif

或实际规格:

#ifdef __cplusplus
    #define __THROW(x) throw(x)
#else
    #define __THROW(x)
#endif

如您所见,在 C 构建中,它扩展为空。在 C++ 中,它可以满足您的期望。这允许供应商重复使用相同的文件。


只是吹毛求疵,这并不完全正确:“(这只是一个 C 库 - 与 C++ 无关)”

C++ 标准库包括使用 C 标准库的能力。实际的标头是<cxxx>,其中xxx 是C 标头名称。也就是说,要在 C++ 中包含 C 标头 <stdlib.h>,您需要执行 <cstdlib>。所以它确实与C++有关。 :)

这就是你看到你所做的代码的原因。为两种不同的语言复制标题将是维护和清洁的噩梦。

【讨论】:

  • 谢谢你的回答很有帮助。
  • THROW 宏定义如下:如果没有定义 __cplusplus #define __THROW __attribute (( nothrow LEAF))。如果定义了 __cplusplus,则 __THROW 扩展到 throw()。 __LEAF 定义如下:#define __LEAF , __leaf
  • 如果定义了 GNUC 则为真,否则 __THROW 在 c 和 c++ 中是无用的扩展
【解决方案2】:

你可以的

cpp -include stdlib.h -dM /dev/null  |grep '#define __THROW '

了解它实际扩展到什么。

在我的系统上,我得到:

#define __THROW __attribute__ ((__nothrow__ __LEAF))

nothrowleaf 属性描述于 https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes 如下:

叶子

leaf 使用该属性调用外部函数必须返回到 当前编译单元仅通过返回或通过异常处理。 特别是,叶函数不允许调用回调 从当前编译单元直接传递给它的函数 调用单元导出的函数,或者 longjmp 到单元中。叶子 函数可能仍会从其他编译单元调用函数,并且 因此它们不一定是叶子,因为它们不包含 函数调用。该属性适用于库函数 改进数据流分析。编译器提示任何 无法使用未转义当前编译单元的数据或 由叶函数修改。例如,sin 函数是一个叶子 函数,但 qsort 不是。

请注意,叶函数可能会间接运行定义的信号处理程序 在使用静态变量的当前编译单元中。相似地, 当惰性符号解析生效时,叶函数可能会调用 其解析器功能或实现功能的间接功能 在当前编译单元中定义并使用静态变量。 没有符合标准的方法来编写这样的信号处理程序, 解析器功能或实现功能,以及您最好的 可以做的就是去掉leaf属性或者标记所有这样的静态 变量易变。最后,对于支持符号的基于 ELF 的系统 干预,应注意在定义的功能 当前编译单元不会意外插入其他符号 基于定义的标准模式和定义的功能测试宏; 否则会添加一个无意的回调。

该属性对当前定义的函数没有影响 编译单元。这是为了方便合并多个 编译单元合二为一,例如,通过使用链接时间 优化。出于这个原因,该属性不允许在类型上 注释间接调用。

不扔

nothrow nothrow 属性用于通知编译器 函数不能抛出异常。例如,大多数函数在 可以保证标准 C 库不会抛出异常 使用函数指针的 qsort 和 bsearch 的显着例外 论据。

__attribute__((nothrow)) 在 C 中的含义在 gcc - what is attribute nothrow used for? 得到回答。基本上,它是为了与 C++ 代码合作,如果函数永远不会回调抛出异常的 C++ 代码,你可以使用它。

【讨论】:

    【解决方案3】:

    要回答有关“此函数是可能的取消点,因此未标记为 __THROW”的其他问题:这涉及多线程。您可以“取消”一个线程,但在达到取消点之前它实际上不会“取消”。更多信息:http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

    【讨论】:

    • 谢谢。完全更改为另一个链接,该链接仍然提供有用的信息。
    猜你喜欢
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多