Почему __FUNCTION__ не определен?

У меня есть библиотека C++, которая использует предопределенный макрос __FUNCTION__, в виде crtdefs.h. Макрос задокументирован здесь. Вот мое использование:

my.cpp

#include <crtdefs.h>
...
void f()
{
    L(__FUNCTIONW__ L" : A diagnostic message");
}

static void L(const wchar_t* format, ...)
{
    const size_t BUFFERLENGTH = 1024;
    wchar_t buf[BUFFERLENGTH] = { 0 };
    va_list args;
    va_start(args, format);
    int count = _vsnwprintf_s(buf, BUFFERLENGTH, _TRUNCATE, format, args);
    va_end(args);
    if (count != 0)
    {
        OutputDebugString(buf);
    }
}

crtdefs.h

#define __FUNCTIONW__ _STR2WSTR(__FUNCTION__) 

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

Когда я компилирую библиотеку, я получаю эту ошибку:

идентификатор "L__FUNCTION__" не определен.

Согласно документации, макрос не раскрывается, если /P или /EP передаются компилятору. Я проверил, что это не так. Существуют ли другие условия, когда этот макрос недоступен?

3 ответа

Решение

Просто используйте

L(__FUNCTION__    L" : A diagnostic message");

Когда смежные строковые литералы объединяются, результатом будет широкая строка, если какой-либо из компонентов был.

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


Так как ваш L Функция оборачивает vsprintf, вы также можете использовать:

L(L"%hs : A diagnostic message", __func__);

поскольку __func__ стандартизирован как узкая строка, %hs спецификатор формата подходит.


Правило находится в 2.14.5p13:

На этапе перевода 6 (2.2) смежные строковые литералы объединяются. Если оба строковых литерала имеют одинаковый префикс кодировки, результирующий конкатенированный строковый литерал имеет этот префикс кодировки. Если один строковый литерал не имеет префикса кодировки, он обрабатывается как строковый литерал того же префикса кодирования, что и другой операнд. Если строковый литерал UTF-8 находится рядом с широким строковым литеральным токеном, программа является некорректной. Любые другие объединения условно поддерживаются поведением, определяемым реализацией.

Вы перечисляете ошибку как это:

identifier "L__FUNCTION__" is undefined.

Обратите внимание, это говорит "L__FUNCTION__"не определено, не"__FUNCTION__".

Не использовать __FUNCTIONW__ в вашем коде. М.С. не документировал это на странице, на которую вы ссылались, они документировали __FUNCTION__, И вам не нужно расширять __FUNCTION__,

ETA: Я также отмечаю, что вы не назначаете эту строку чему-либо или печатаете ее в любом случае в f(),

Я думаю, что определение __FUNCTIONW__ это неверно. (Я знаю, что вы не написали это.)

От: http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html

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

По крайней мере, в текущем GCC, вы не можете предварять L в __FUNCTION__потому что это все равно что пытаться подготовить L к переменной. Вероятно, была версия VC++ (как в GCC), где это работало бы, но вы не используете эту версию.

Другие вопросы по тегам