为什么我看到一个C库?

时间:2021-01-28 15:06:14

When I do: less /usr/include/stdio.h (which is only a C library - nothing to do with C++)

当我这样做时:减少/usr/include/stdio.h(它只是一个C库——与c++无关)

I see __THROW after quite a few function declarations. Also, comments above a few functions say that 'This function is a possible cancellation point and therefore not marked with __THROW' What is all this for?

在一些函数声明之后,我看到了__THROW。此外,在一些函数上面的注释说:“这个函数是一个可能的取消点,因此不标记为__THROW”,这一切是为了什么?

throw is meant to be for exception handling...but as far as I know, C doesn't provide any support for it.

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

Please explain.

请解释一下。

3 个解决方案

#1


36  

This header is likely shared between the C and C++ compiler for that vendor. Did you look what __THROW is defined as?

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

I suspect something akin to:

我怀疑类似于:

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

Or for actual specifications:

或实际规格:

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

As you can see, in a C build, it expands to nothing. In C++, it does what you expect. This allows vendors to reuse the same file.

正如您所看到的,在C构建中,它扩展为零。在c++中,它执行您所期望的操作。这允许供应商重用相同的文件。


Just to nitpick, this isn't entirely true: "(which is only a C library - nothing to do with C++)"

只是吹毛求疵,这并不是完全正确的:“(它只是一个C库——与c++没有任何关系)”

The C++ standard library includes the ability to use the C standard library. The actual header is <cxxx> where xxx is the C header name. That is, to include the C header <stdlib.h> in C++, you do <cstdlib>. So it does have to do with C++. :)

c++标准库包括使用C标准库的能力。实际的标题是 ,其中xxx是C标题名称。也就是说,要包含C头 。这和c++有关。:) 。在c++中,你做的是

This is why you see the code you do. Duplicating the header for two different languages would be a nightmare for maintenance and cleanliness.

这就是为什么您会看到您所做的代码。为两种不同的语言复制头将是维护和清洁的噩梦。

#2


4  

To answer your other question concerning "This function is a possible cancellation point and therefore not marked with __THROW": This deals with multi-threading. You can "cancel" a thread, but it won't actually "cancel" until it reaches a cancellation point. Some more info: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

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

#3


2  

You can do

你可以做

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

to learn what it actually expands to.

去了解它实际上扩展到什么。

On my system, I get:

在我的系统中,我得到:

#define __THROW __attribute__ ((__nothrow__ __LEAF))

The nothrow and leaf attributes are described at https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes as follows:

nothrow和leaf属性在https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html# common - attributes如下所示:

leaf

leaf Calls to external functions with this attribute must return to the current compilation unit only by return or by exception handling. In particular, a leaf function is not allowed to invoke callback functions passed to it from the current compilation unit, directly call functions exported by the unit, or longjmp into the unit. Leaf functions might still call functions from other compilation units and thus they are not necessarily leaf in the sense that they contain no function calls at all. The attribute is intended for library functions to improve dataflow analysis. The compiler takes the hint that any data not escaping the current compilation unit cannot be used or modified by the leaf function. For example, the sin function is a leaf function, but qsort is not.

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

Note that leaf functions might indirectly run a signal handler defined in the current compilation unit that uses static variables. Similarly, when lazy symbol resolution is in effect, leaf functions might invoke indirect functions whose resolver function or implementation function is defined in the current compilation unit and uses static variables. There is no standard-compliant way to write such a signal handler, resolver function, or implementation function, and the best that you can do is to remove the leaf attribute or mark all such static variables volatile. Lastly, for ELF-based systems that support symbol interposition, care should be taken that functions defined in the current compilation unit do not unexpectedly interpose other symbols based on the defined standards mode and defined feature test macros; otherwise an inadvertent callback would be added.

注意,leaf函数可能间接运行当前编译单元中定义的使用静态变量的信号处理程序。类似地,当惰性符号解析有效时,leaf函数可能调用间接函数,其解析函数或实现函数在当前编译单元中定义并使用静态变量。编写这样的信号处理程序、解析器函数或实现函数没有遵循标准的方法,最好的方法是删除leaf属性或标记所有此类静态变量。最后,对于支持符号插入的基于elf的系统,应该注意,当前编译单元中定义的函数不会意外地基于定义的标准模式和定义的特性测试宏插入其他符号;否则将添加一个无意的回调。

The attribute has no effect on functions defined within the current compilation unit. This is to allow easy merging of multiple compilation units into one, for example, by using the link-time optimization. For this reason the attribute is not allowed on types to annotate indirect calls.

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

nothrow

nothrow

nothrow The nothrow attribute is used to inform the compiler that a function cannot throw an exception. For example, most functions in the standard C library can be guaranteed not to throw an exception with the notable exceptions of qsort and bsearch that take function pointer arguments.

nothrow属性用于通知编译器函数不能抛出异常。例如,标准C库中的大多数函数都可以保证不会抛出异常,但qsort和bsearch有明显的例外,它们使用函数指针参数。

What __attribute__((nothrow)) means in C is answered at gcc - what is attribute nothrow used for? . Basically, it's for cooperation with C++ code, and you can use it if the function won't ever call back to exception-throwing C++ code.

在C中,__attribute__(nothrow)是什么意思?。基本上,它是用于与c++代码合作的,如果函数不回调异常(抛出c++代码),您可以使用它。

#1


36  

This header is likely shared between the C and C++ compiler for that vendor. Did you look what __THROW is defined as?

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

I suspect something akin to:

我怀疑类似于:

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

Or for actual specifications:

或实际规格:

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

As you can see, in a C build, it expands to nothing. In C++, it does what you expect. This allows vendors to reuse the same file.

正如您所看到的,在C构建中,它扩展为零。在c++中,它执行您所期望的操作。这允许供应商重用相同的文件。


Just to nitpick, this isn't entirely true: "(which is only a C library - nothing to do with C++)"

只是吹毛求疵,这并不是完全正确的:“(它只是一个C库——与c++没有任何关系)”

The C++ standard library includes the ability to use the C standard library. The actual header is <cxxx> where xxx is the C header name. That is, to include the C header <stdlib.h> in C++, you do <cstdlib>. So it does have to do with C++. :)

c++标准库包括使用C标准库的能力。实际的标题是 ,其中xxx是C标题名称。也就是说,要包含C头 。这和c++有关。:) 。在c++中,你做的是

This is why you see the code you do. Duplicating the header for two different languages would be a nightmare for maintenance and cleanliness.

这就是为什么您会看到您所做的代码。为两种不同的语言复制头将是维护和清洁的噩梦。

#2


4  

To answer your other question concerning "This function is a possible cancellation point and therefore not marked with __THROW": This deals with multi-threading. You can "cancel" a thread, but it won't actually "cancel" until it reaches a cancellation point. Some more info: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

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

#3


2  

You can do

你可以做

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

to learn what it actually expands to.

去了解它实际上扩展到什么。

On my system, I get:

在我的系统中,我得到:

#define __THROW __attribute__ ((__nothrow__ __LEAF))

The nothrow and leaf attributes are described at https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes as follows:

nothrow和leaf属性在https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html# common - attributes如下所示:

leaf

leaf Calls to external functions with this attribute must return to the current compilation unit only by return or by exception handling. In particular, a leaf function is not allowed to invoke callback functions passed to it from the current compilation unit, directly call functions exported by the unit, or longjmp into the unit. Leaf functions might still call functions from other compilation units and thus they are not necessarily leaf in the sense that they contain no function calls at all. The attribute is intended for library functions to improve dataflow analysis. The compiler takes the hint that any data not escaping the current compilation unit cannot be used or modified by the leaf function. For example, the sin function is a leaf function, but qsort is not.

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

Note that leaf functions might indirectly run a signal handler defined in the current compilation unit that uses static variables. Similarly, when lazy symbol resolution is in effect, leaf functions might invoke indirect functions whose resolver function or implementation function is defined in the current compilation unit and uses static variables. There is no standard-compliant way to write such a signal handler, resolver function, or implementation function, and the best that you can do is to remove the leaf attribute or mark all such static variables volatile. Lastly, for ELF-based systems that support symbol interposition, care should be taken that functions defined in the current compilation unit do not unexpectedly interpose other symbols based on the defined standards mode and defined feature test macros; otherwise an inadvertent callback would be added.

注意,leaf函数可能间接运行当前编译单元中定义的使用静态变量的信号处理程序。类似地,当惰性符号解析有效时,leaf函数可能调用间接函数,其解析函数或实现函数在当前编译单元中定义并使用静态变量。编写这样的信号处理程序、解析器函数或实现函数没有遵循标准的方法,最好的方法是删除leaf属性或标记所有此类静态变量。最后,对于支持符号插入的基于elf的系统,应该注意,当前编译单元中定义的函数不会意外地基于定义的标准模式和定义的特性测试宏插入其他符号;否则将添加一个无意的回调。

The attribute has no effect on functions defined within the current compilation unit. This is to allow easy merging of multiple compilation units into one, for example, by using the link-time optimization. For this reason the attribute is not allowed on types to annotate indirect calls.

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

nothrow

nothrow

nothrow The nothrow attribute is used to inform the compiler that a function cannot throw an exception. For example, most functions in the standard C library can be guaranteed not to throw an exception with the notable exceptions of qsort and bsearch that take function pointer arguments.

nothrow属性用于通知编译器函数不能抛出异常。例如,标准C库中的大多数函数都可以保证不会抛出异常,但qsort和bsearch有明显的例外,它们使用函数指针参数。

What __attribute__((nothrow)) means in C is answered at gcc - what is attribute nothrow used for? . Basically, it's for cooperation with C++ code, and you can use it if the function won't ever call back to exception-throwing C++ code.

在C中,__attribute__(nothrow)是什么意思?。基本上,它是用于与c++代码合作的,如果函数不回调异常(抛出c++代码),您可以使用它。