Подтвердить что ты не робот

Почему я вижу THROW в библиотеке C?

Когда я это сделаю: less /usr/include/stdio.h (который является только C-библиотекой - не имеет ничего общего с С++)

Я вижу __THROW после нескольких объявлений функций. Кроме того, комментарии выше нескольких функций говорят, что "эта функция является возможной точкой отмены и поэтому не помечена знаком __THROW" Для чего это все?

throw предназначен для обработки исключений... но, насколько я знаю, C не предоставляет никакой поддержки для него.

Пожалуйста, объясните.

4b9b3361

Ответ 1

Этот заголовок, вероятно, будет совместно использоваться компилятором C и С++ для этого поставщика. Вы посмотрели, что __THROW определяется как?

Я подозреваю что-то похожее на:

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

Или для настоящих спецификаций:

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

Как вы можете видеть, в сборке C он расширяется до нуля. В С++ он делает то, что вы ожидаете. Это позволяет продавцам повторно использовать один и тот же файл.


Просто для nitpick это не совсем так: "(это только C-библиотека - не имеет ничего общего с С++)"

Стандартная библиотека С++ включает в себя возможность использования стандартной библиотеки C. Фактический заголовок <cxxx>, где xxx - это имя заголовка C. То есть, чтобы включить заголовок C <stdlib.h> в С++, вы делаете <cstdlib>. Так что это связано с С++.:)

Вот почему вы видите код, который вы делаете. Дублирование заголовка для двух разных языков было бы кошмаром для обслуживания и чистоты.

Ответ 2

Чтобы ответить на другой вопрос, касающийся "Эта функция является возможной точкой отмены и поэтому не помечена __THROW": это касается многопоточности. Вы можете "отменить" поток, но он фактически не "отменит", пока не достигнет точки отмены. Дополнительная информация: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

Ответ 3

Вы можете сделать

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 нет.

Обратите внимание, что функции листа могут косвенно запускать обработчик сигнала в текущем блоке компиляции, который использует статические переменные. По аналогии, когда действует ленивое разрешение символа, функции листа могут ссылаться косвенные функции, функция распознавания или функция реализации определяется в текущем модуле компиляции и использует статические переменные. Нет стандартного способа записи такого обработчика сигнала, функцию распознавателя или функцию реализации, и лучшее, что вы может сделать это, чтобы удалить атрибут листа или отметить все такие статические переменные нестабильны. Наконец, для ELF-систем, поддерживающих символ интерпозиции, следует проявлять осторожность, чтобы функции, определенные в текущий блок компиляции не неожиданно вставляет другие символы на основе режима определенных стандартов и определенных макросов теста функций; в противном случае будет добавлен непреднамеренный обратный вызов.

Атрибут не влияет на функции, определенные в текущем сбор единица измерения. Это позволяет легко слить несколько единицы компиляции в одну, например, используя время ссылки оптимизация. По этой причине атрибут не допускается к типам аннотировать косвенные вызовы.

nothrow

nothrow Атрибут nothrow используется для информирования компилятора о том, что функция не может генерировать исключение. Например, большинство функций в стандартная библиотека C может быть гарантирована, чтобы не исключать заметные исключения qsort и bsearch, которые принимают указатель на функцию Аргументы.

Что означает __attribute__((nothrow)) в C, ответят на gcc - для чего используется атрибут nothrow для?. В принципе, это для сотрудничества с С++-кодом, и вы можете использовать его, если функция никогда не перезвонит на код С++, бросающий исключение.