2010-03-21 17 views
28

Cuando hago: less /usr/include/stdio.h (que es sólo una biblioteca de C - nada que ver con C++)¿Por qué veo THROW en una biblioteca de C?

veo __THROW después de un buen número de declaraciones de funciones. Además, los comentarios anteriores algunas funciones dicen que 'Esta función es un posible punto de cancelación y, por lo tanto, no está marcado con __THROW' ¿Qué es todo esto?

throw está destinado a la gestión de excepciones ... pero hasta donde yo sé, C no proporciona ningún soporte para ello.

Explique.

+1

¿Qué compilador? Me parece que es GCC. (Tenga en cuenta que no existe una "biblioteca estándar", por lo que es útil especificar qué implementación utiliza). – GManNickG

+1

Ahh, veo que ha descubierto glibc :) –

Respuesta

34

Este encabezado probablemente se comparte entre el compilador C y C++ para ese proveedor. ¿Usted miró lo que __THROW se define como?

sospecho algo parecido a:

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

O para las especificaciones reales:

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

Como se puede ver, en una versión de C, se expande a nada. En C++, hace lo que esperas. Esto permite a los proveedores reutilizar el mismo archivo.


Sólo que pequeñez, esto no es del todo cierto: "(que es sólo una biblioteca de C - nada que ver con C++)"

La biblioteca de C++ estándar incluye la capacidad de utilizar la C biblioteca estándar. El encabezado real es <cxxx> donde xxx es el nombre del encabezado C. Es decir, para incluir el encabezado C <stdlib.h> en C++, usted hace <cstdlib>. Entonces tiene que ver con C++. :)

Es por eso que ves el código que haces. Duplicar el encabezado para dos idiomas diferentes sería una pesadilla para el mantenimiento y la limpieza.

+0

Gracias por su respuesta, es muy útil. –

3

Para responder a su otra pregunta sobre "Esta función es un posible punto de cancelación y, por lo tanto, no está marcada con __THROW": se trata de multi-threading. Puede "cancelar" un hilo, pero en realidad no se "cancelará" hasta que llegue a un punto de cancelación. Algunos más información: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

+0

el enlace está roto. –

+0

Gracias. Cambió por completo a otro enlace que todavía proporciona información útil. – Ioan

2

Usted puede hacer

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

a aprender lo que en realidad se expande a.

En mi sistema, me sale:

#define __THROW __attribute__ ((__nothrow__ __LEAF)) 

El nothrow y hoja atributos se describen en https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes de la siguiente manera:

hoja

Las llamadas a funciones externas con este atributo deben regresar a la unidad de compilación actual solo por devolución o por manejo de excepciones. En particular, una función de hoja no puede invocar las funciones de devolución de llamada que le han pasado desde la unidad de compilación actual, directamente funciones de llamada exportadas por la unidad, o longjmp a la unidad. Las funciones de Leaf aún pueden llamar a funciones de otras unidades de compilación y , por lo que no son necesariamente hojas en el sentido de que no contienen ninguna llamada a función . El atributo está destinado a las funciones de la biblioteca para mejorar el análisis del flujo de datos. El compilador toma la sugerencia de que los datos que no escapen de la unidad de compilación actual no se pueden usar o modificados por la función de hoja. Por ejemplo, la función sin es una función de hoja , pero qsort no lo es.

Tenga en cuenta que las funciones de hoja pueden ejecutar indirectamente un manejador de señal definido en la unidad de compilación actual que usa variables estáticas. De manera similar, cuando la resolución de símbolos vagos está activa, las funciones de hoja pueden invocar a las funciones indirectas cuya función de resolución o función de implementación se define en la unidad de compilación actual y usa variables estáticas. No existe una forma estándar de escribir tal controlador de señal, función de resolución, o función de implementación, y lo mejor que puede hacer es eliminar el atributo hoja o marcar todas las variables estáticas volátiles. Por último, para sistemas basados ​​en ELF que admiten la interposición del símbolo , se debe tener cuidado de que las funciones definidas en la unidad de compilación actual no interpongan inesperadamente otros símbolos en función del modo de estándares definido y las macros de características definidas; de lo contrario, se agregará una devolución de llamada inadvertida.

El atributo no tiene ningún efecto en las funciones definidas dentro de la unidad de compilación actual . Esto es para permitir la fusión fácil de múltiples unidades de compilación en una, por ejemplo, utilizando la optimización en tiempo de enlace. Por esta razón, no se permite el atributo en los tipos a anotar llamadas indirectas.

nothrow

nothrow El atributo nothrow se utiliza para informar al compilador que una función no puede lanzar una excepción. Por ejemplo, se puede garantizar que la mayoría de las funciones en la biblioteca C estándar no arrojen una excepción con las notables excepciones de qsort y bsearch que toman los argumentos del puntero de función .

Lo que __attribute__((nothrow)) significa en C se responde en gcc - what is attribute nothrow used for?. Básicamente, es para la cooperación con el código C++, y puede usarlo si la función no volverá a llamar al código C++ de lanzamiento de excepción.

Cuestiones relacionadas