Есть необходимость в лог писать имя функции, которая упала...
Есть код, который во всяком случае компиляется...
итак:
#ifdef WIN32
#define MRSWIDEN2(x) L ## x
#else
#define MRSWIDEN2(x) L ## #x
#endif
#define MRSWIDEN(x) MRSWIDEN2(x)
#ifdef WIN32
#define __WMRSFUNC__ MRSWIDEN(__FUNCTION__)
#else //!WIN32
#define __WMRSFUNC__ MRSWIDEN(__PRETTY_FUNCTION__)
#endif // WIN32
#define ERR_LOG(log, res, msg_err) \
log.AddMessage(res, __WMRSFUNC__ L" : " msg_err);
...
if (mrsResult != MRS_OK)
{
ERR_LOG(m_AppLog, mrsResult, L"Can't read Product table");
}
Под виндой все работает нормально...
под линухом после препроцессора получается чтото типа:
m_AppLog.AddMessage(mrsResult, L"__PRETTY_FUNCTION__" L" : " L"Can't read Product table");
такой вариант мне, конечно не подходит
если объявить так (так же как в виндовой ветке):
#define MRSWIDEN2(x) L ## x
то имеем после препроцессора код
m_AppLog.AddMessage(mrsResult, L__PRETTY_FUNCTION__ L" : " L"Can't read Product table");
Само собой, что это тоже не канает, т.к. компилер не может найти L__PRETTY_FUNCTION__
Как мне подправить этот код?
Здравствуйте, Graf Alex, Вы писали:
GA>Как мне подправить этот код?
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
# define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_A((text))
# define BOOST_PP_STRINGIZE_A(arg) BOOST_PP_STRINGIZE_B ## (arg)
# define BOOST_PP_STRINGIZE_B(arg) BOOST_PP_STRINGIZE_I ## arg
# elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
# define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_OO((text))
# define BOOST_PP_STRINGIZE_OO(par) BOOST_PP_STRINGIZE_I ## par
# else
# define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_I(text)
# endif
#
# define BOOST_PP_STRINGIZE_I(text) #text
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Graf Alex, Вы писали:
GA>>Как мне подправить этот код?
R>R># if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
R># define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_A((text))
R># define BOOST_PP_STRINGIZE_A(arg) BOOST_PP_STRINGIZE_B ## (arg)
R># define BOOST_PP_STRINGIZE_B(arg) BOOST_PP_STRINGIZE_I ## arg
R># elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
R># define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_OO((text))
R># define BOOST_PP_STRINGIZE_OO(par) BOOST_PP_STRINGIZE_I ## par
R># else
R># define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_I(text)
R># endif
R>#
R># define BOOST_PP_STRINGIZE_I(text) #text
R>
R> 
1) Нам только буста и не хватает

2) Эта ничем не помогает по поводу __PRETTY_FUNCTION__
3) Это ничем не помогает по поводу юникода
Здравствуйте, Graf Alex, Вы писали:
GA>1) Нам только буста и не хватает
А причём здесь boost? Это просто работающий код. Абстрагируйся от деталей
GA>2) Эта ничем не помогает по поводу __PRETTY_FUNCTION__
GA>3) Это ничем не помогает по поводу юникода
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
# define BOOST_PP_WSTRINGIZE(text) BOOST_PP_WSTRINGIZE_I(text)
# else
# define BOOST_PP_WSTRINGIZE(text) BOOST_PP_WSTRINGIZE_OO((text))
# define BOOST_PP_WSTRINGIZE_OO(par) BOOST_PP_WSTRINGIZE_I ## par
# endif
#
# define BOOST_PP_WSTRINGIZE_I(text) BOOST_PP_WSTRINGIZE_II(#text)
# define BOOST_PP_WSTRINGIZE_II(str) L ## str
Обрабатывай имя функции отдельно от сообщения, как ANSI. Заодно и на размере EXE чуть сэкономишь.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Здравствуйте, Graf Alex, Вы писали:
GA>Как мне подправить этот код?
Никак. C99::6.4.2.2:
The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration
static const char __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosing function.
__FUNCTION__ и __PRETTY_FUNCTION__ из GCC действуют так же:
http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html.
Причем __FUNC* в MSVC вообще никак не специфицируют свое поведение: «
returns the undecorated name of the enclosing function (as a string)».
Так что я бы не стал рассчитывать на то, что эти идентификаторы будут макросами. И для кроссплатформенности я бы использовал
BOOST_CURRENT_FUNCTION (этот заголовочный файл не зависит от других файлов Boost).
Придется конвертировать в runtime (что-то вроде std::wstring(BOOST_CURRENT_FUNCTION, BOOST_CURRENT_FUNCTION + strlen(BOOST_CURRENT_FUNCTION))).
И еще что — свои идентификаторы нельзя называть с двумя символами подчеркивания (или начинать их с _ и прописной буквы), потому что C++03::17.4.3.1.2.