Почему я вижу THROW в библиотеке C? - PullRequest
36 голосов
/ 21 марта 2010

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

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

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

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

Ответы [ 3 ]

40 голосов
/ 21 марта 2010

Этот заголовок, вероятно, совместно используется компилятором 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 <stdlib.h> в C ++, вы делаете <cstdlib>. Так что это имеет отношение к C ++. :)

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

5 голосов
/ 22 марта 2010

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

4 голосов
/ 21 августа 2016

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

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? . По сути, это для сотрудничества с кодом C ++, и вы можете использовать его, если функция никогда не будет вызывать вызывающий исключение код C ++.

...