Как узнать, существует ли этот макрос препроцессора? - PullRequest
4 голосов
/ 28 октября 2010

Я хочу знать, как узнать, может ли макрос препроцессора __PRETTY_FUNCTION__ использоваться с данным компилятором (поскольку он должен быть нестандартным). Как я могу проверить это в заголовочном файле? Что я хочу сделать, это что-то вроде:

#ifndef __PRETTY_FUNCTION__
   #define __PRETTY_FUNCTION__ __func__
#endif

Но я предполагаю, что случится, если препроцессор определит макрос на месте для каждой функции, поэтому мне интересно, есть ли смысл в __PRETTY_FUNCTION__ (в отличие от __FILE__ или __LINE__) вне функции. Это правда или я могу просто использовать код выше? Если нет, как я могу проверить это?

РЕДАКТИРОВАТЬ: Я попробовал это. __PRETTY_FUNCTION__ не определено вне функции (я не проверял внутри класса). Так что должен быть другой путь.

РЕДАКТИРОВАТЬ2: На самом деле простой взлом был бы сделать это :):

void Dummy()
{
    #ifndef __PRETTY_FUNCTION__
       #define __PRETTY_FUNCTION__ __func__
    #endif
}

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

1 Ответ

4 голосов
/ 28 октября 2010

Вы, вероятно, должны знать, какой компилятор вы используете.Для GCC (Коллекция компиляторов GNU) вы, вероятно, протестируете:

#ifdef __GNUG__
...use __PRETTY_FUNCTION__
#endif

Вы можете проверить версию компилятора, если знаете, какая из них представила функцию, и вы рискуете скомпилировать свой кодболее старая версия.

В руководстве GCC (4.4.1) написано:

В C __PRETTY_FUNCTION__ - это еще одно имя для __func__.Однако в C ++ __PRETTY_FUNCTION__ содержит сигнатуру типа функции, а также ее голое имя.Например, эта программа:

 extern "C" {
     extern int printf (char *, ...);
 }
 class a {
 public:
     void sub (int i)
     {
         printf ("__FUNCTION__ = %s\n", __FUNCTION__);
         printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__);
     }
 };
 int
 main (void)
 {
     a ax;
     ax.sub (0);
     return 0;
 }

дает такой вывод:

 __FUNCTION__ = sub
 __PRETTY_FUNCTION__ = void a::sub(int)

Эти идентификаторы не являются макросами препроцессора.В GCC 3.3 и ранее, только в C, __FUNCTION__ и __PRETTY_FUNCTION__ обрабатывались как строковые литералы;они могут быть использованы для инициализации массивов символов и могут быть объединены с другими строковыми литералами.GCC 3.4 и более поздние версии рассматривают их как переменные, например __func__.В C ++ __FUNCTION__ и __PRETTY_ FUNCTION__ всегда были переменными.

...