__func__ или __FUNCTION__ или ручной const char * id? - PullRequest
20 голосов
/ 10 августа 2011

Мне интересно, насколько широко поддерживаются __func__ (часть C99, но я компилирую как C89) и __FUNCTION__.

У меня есть старая кодовая база, в которой в основном используются ручные const char* id; переменные, которые затем передаются в различные (в основном, журнальные) функции. Я хотел бы избавиться от этого и переместить имя функции в макрос.

Ответы [ 3 ]

10 голосов
/ 20 сентября 2013

Предопределенный идентификатор __func__ был добавлен в стандарт ISO C 1999 года;более старый стандарт 1990 C. его не имеет.

Поддержка __func__ в компиляторах до C99 будет зависеть от того, какой компилятор вы используете.

Современные версии поддержки gcc __func__ даже в режиме C90 (-ansi или -std=c89).

До того, как __func__ был добавлен в стандарт, gcc реализовал свое собственное эквивалентное расширение, но с именем __FUNCTION__.(gcc также поддерживает __PRETTY_FUNCTION__, что идентично __func__ и __FUNCTION__ для C, но предоставляет дополнительную информацию на C ++.)

Руководство gcc дает несколько советов:

__FUNCTION__ - другое название для __func__.Более старые версии GCC распознают только это имя.Однако это не стандартизировано.Для максимальной переносимости мы рекомендуем использовать __func__, но предоставить препроцессорное резервное определение:

 #if __STDC_VERSION__ < 199901L
 # if __GNUC__ >= 2
 #  define __func__ __FUNCTION__
 # else
 #  define __func__ "<unknown>"
 # endif
 #endif

, что подразумевает, что gcc добавил поддержку __FUNCTION__ в версии 2. gcc 2.0 был выпущен в 1992 году;очень маловероятно, что вы используете версию gcc, которая не поддерживает по крайней мере __FUNCTION__, если нет __func__.

Обратите внимание, что поскольку __func__ и __FUNCTION__ являются предопределенными идентификаторами, а немакросы, вам нужно только #define один раз, а не в каждой функции.С другой стороны, вы не можете использовать #ifdef __func__ или #ifdef __FUNCTION__ для определения уровня поддержки.

Как и для других компиляторов, быстрый эксперимент показывает, что Microsoft Visual C ++ 2010 Express поддерживает __FUNCTION__,но не __func__ или __PRETTY_FUNCTION__ при компиляции кода C.Приведенный выше блок кода из руководства gcc компилируется в MSVC, но в результате __func__ определяется как "<unknown>".Не должно быть слишком сложно настроить его, чтобы признать, что MSVC поддерживает __FUNCTION__.(Я не знаю, делают ли это более старые версии.) Возможно, вы можете использовать предопределенный макрос _MSC_VER для этого. В документации Microsoft говорится, что поддержка __FUNCTION__ восходит по крайней мере к выпуску 2003 года, который устанавливает _MSC_VER в 1300, поэтому изменение второй строки на

# if __GNUC >= 2 || _MSC_VER >= 1300

хорошее начало.(Это вполне могло бы поддерживаться в более ранних выпусках.)

Для компиляторов, отличных от gcc и MSVC, вам придется обратиться к их соответствующей документации - но в любом случае блок кода, рекомендованный в gccРуководство должно работать для любого компилятора, в худшем случае отступая к "<unknown>".

6 голосов
/ 10 августа 2011

Заголовок boost current_function.hpp содержит несколько #define s для способов получения текущей функции на разных платформах.

Это не означает, что эти платформы не поддерживаютдругие способы получения текущей функции, но выбор, сделанный для повышения, вероятно, будет представлять собой хороший (если не самый хороший) способ получения информации на этих платформах.

Адаптация этого заголовка для вашего кода (идля C) вполне может быть то, что вам нужно.

0 голосов
/ 10 августа 2011

Я считаю, что независимо от того, какой стандарт C используется (если C89 или C99).Более важным фактором является используемый компилятор, поскольку именно он будет реализовывать __func__.Новейшие компиляторы GCC добавят __func__ независимо от используемого стандарта.Я думаю.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...