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

__func__ или __FUNCTION__ или ручной const char * id?

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

До стандарта __func__ был добавлен стандарт, gcc реализовал собственное эквивалентное расширение, но с именем __FUNCTION__. (gcc также поддерживает __PRETTY_FUNCTION__, который идентичен __func__ и __FUNCTION__ для 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 С++ 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>".

Ответ 3

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