48

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

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

throw旨在用于异常处理......但据我所知,C 不提供任何支持。

请解释。

4

3 回答 3

49

该头文件可能在该供应商的 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>Cxxx标头名称的位置。也就是说,要<stdlib.h>在 C++ 中包含 C 标头,您需要<cstdlib>. 所以它确实与C++有关。:)

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

于 2010-03-21T08:22:04.963 回答
11

你可以做

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

了解它实际扩展到什么。

在我的系统上,我得到:

#define __THROW __attribute__ ((__nothrow__ __LEAF))

nothrow和Leaf属性在 https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes 中 描述 如下

叶子

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

请注意,叶函数可能会间接运行在当前编译单元中定义的使用静态变量的信号处理程序。类似地,当惰性符号解析生效时,叶函数可能会调用间接函数,其解析器函数或实现函数在当前编译单元中定义并使用静态变量。没有符合标准的方法来编写这样的信号处理程序、解析器函数或实现函数,您能做的最好的事情就是删除叶子属性或将所有此类静态变量标记为 volatile。最后,对于支持符号插入的基于 ELF 的系统,应注意当前编译单元中定义的函数不会意外地插入基于定义的标准模式和定义的功能测试宏的其他符号;

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

不扔

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

__attribute__((nothrow))在 gcc 中回答了 C 中的什么意思- 属性 nothrow 的用途是什么?. 基本上,它是用于与 C++ 代码合作的,如果函数永远不会回调抛出异常的 C++ 代码,则可以使用它。

于 2016-08-21T15:50:36.533 回答
6

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

于 2010-03-22T18:01:46.253 回答