当我这样做时:
less /usr/include/stdio.h
(这只是一个C库 - 与C ++无关)
在很多函数声明后我看到__THROW
。
此外,一些函数上面的注释表示'此函数是一个可能的取消点,因此没有标记为__THROW
'
这是为了什么?
throw
用于异常处理...但据我所知,C不提供任何支持。
请解释。
答案 0 :(得分:40)
此标头可能在该供应商的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 ++有关。 :)
这就是你看到你所做的代码的原因。复制两种不同语言的标题将是维护和清洁的噩梦。
答案 1 :(得分:5)
要回答您关于“此功能是可能的取消点,因此未标记为__THROW”的其他问题:这涉及多线程。你可以“取消”一个线程,但在到达取消点之前它实际上不会“取消”。更多信息:http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html
答案 2 :(得分:4)
你可以做到
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 如下:
<强>叶强>
leaf使用此属性调用外部函数必须返回 当前编译单元只能通过返回或异常处理。 特别是,不允许叶函数调用回调 函数直接从当前编译单元传递给它 调用本机输出的函数,或longjmp进入单元。叶 函数可能仍然从其他编译单元调用函数 因此,它们不一定是叶子,因为它们不含有 函数调用。该属性适用于库函数 改进数据流分析。编译器接受任何提示 不能使用当前编译单元的数据或不能使用 由叶函数修改。例如,sin函数是叶子 功能,但qsort不是。
请注意,叶函数可能间接运行定义的信号处理程序 在当前使用静态变量的编译单元中。同样的, 当惰性符号解析生效时,叶子函数可能会调用 其解析器功能或实现功能的间接功能 在当前编译单元中定义并使用静态变量。 没有符合标准的方法来编写这样的信号处理程序, 解析器功能或实现功能,以及您的最佳功能 可以做的是删除叶属性或标记所有这样的静态 变量volatile。最后,对于支持符号的基于ELF的系统 介入时,应注意定义的功能 当前编译单元不会意外插入其他符号 基于定义的标准模式和定义的特征测试宏; 否则会添加无意的回调。
该属性对当前定义的函数没有影响 编译单位。这是为了容易合并多个 例如,通过使用链接时间将编译单元合并为一个 优化。因此,类型不允许使用该属性 注释间接调用。
<强>抛出异常强>
nothrow nothrow属性用于通知编译器a 函数不能抛出异常。例如,大部分功能都在 标准C库可以保证不会抛出异常 带有函数指针的qsort和bsearch的值得注意的例外 参数。
在gcc - what is attribute nothrow used for?回答了__attribute__((nothrow))
在C中的含义。基本上,它与C ++代码的合作,如果函数不会回调抛出异常的C ++代码,你可以使用它。