Pregunta ¿Por qué veo THROW en una biblioteca C?


Cuando lo hago: less /usr/include/stdio.h (que es solo una biblioteca C - nada que ver con C ++)

Ya veo __THROW después de bastantes declaraciones de funciones. Además, los comentarios arriba de algunas funciones dicen que 'Esta función es un posible punto de cancelación y, por lo tanto, no está marcada con __THROW' ¿Para qué es todo esto?

throw está destinado para el manejo de excepciones ... pero hasta donde yo sé, C no proporciona ningún soporte para ello.

Por favor explique.


32
2018-03-21 08:16


origen


Respuestas:


Es probable que este encabezado se comparta entre el compilador C y C ++ para ese proveedor. Miraste qué __THROW ¿Se define como?

Sospecho que algo parecido a:

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

O para especificaciones reales:

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

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


Solo para criticar, esto no es del todo cierto: "(que es solo una biblioteca C, nada que ver con C ++)"

La biblioteca estándar de C ++ incluye la capacidad de usar la biblioteca estándar de C. El encabezado real es <cxxx> dónde xxx es el nombre del encabezado C. Es decir, para incluir el encabezado C <stdlib.h> en C ++, lo haces <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.


36
2018-03-21 08:22



Para responder a su otra pregunta con respecto a "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. Algo más de información: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html


4
2018-03-22 18:01



Tu puedes hacer

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

para saber en qué se expande realmente

En mi sistema, obtengo:

#define __THROW __attribute__ ((__nothrow__ __LEAF))

los nothrow y hoja los atributos se describen en https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes como sigue:

hoja

hojas Las llamadas a funciones externas con este atributo deben volver 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 devoluciones de llamada   funciones pasadas desde la unidad de compilación actual, directamente   funciones de llamada exportadas por la unidad o longjmp a la unidad. Hoja   las funciones aún pueden llamar a funciones de otras unidades de compilación y   por lo tanto, no son necesariamente hojas en el sentido de que no contienen   llamadas de función en absoluto. El atributo está destinado para funciones de la biblioteca   para mejorar el análisis del flujo de datos. El compilador toma la sugerencia de que cualquier   los datos que no escapan de la unidad de compilación actual no se pueden usar o   modificado por la función de hoja. Por ejemplo, la función pecado es una hoja   función, pero qsort no lo es.

Tenga en cuenta que las funciones de hoja podrían ejecutar indirectamente un manejador de señal definido   en la unidad de compilación actual que usa variables estáticas. Similar,   cuando la resolución del símbolo perezoso está en vigor, las funciones de hoja podrían invocar   funciones indirectas cuya función de resolución o función de implementación   se define en la unidad de compilación actual y utiliza variables estáticas.   No existe una forma estándar de escribir tal manejador de señal,   función de resolución, o función de implementación, y lo mejor que usted   puede hacer es eliminar el atributo de hoja o marcar todos los estáticos   variables volátiles. Por último, para sistemas basados ​​en ELF que admiten símbolos   interposición, se debe tener cuidado de que las funciones definidas en   la unidad de compilación actual no interpone inesperadamente otros símbolos   basado en el modo de estándares definidos y las macros de pruebas de características definidas;   de lo contrario, se agregaría una devolución de llamada inadvertida.

El atributo no tiene ningún efecto sobre las funciones definidas dentro de la corriente   unidad de compilación. Esto es para permitir una fácil fusión de múltiples   unidades de compilación en una, por ejemplo, mediante el uso del tiempo de enlace   mejoramiento. Por esta razón, el atributo no está permitido en los tipos para   anotar llamadas indirectas.

nothrow

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

Qué __attribute__((nothrow)) significa en C se responde en gcc: ¿para qué se usa el atributo nothrow? . 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.


2
2017-08-21 15:50