Судя по вашим комментариям, цель состоит в том, чтобы иметь макрос, который сочетает в себе имя файла и имя функции (и, возможно, номер строки) в одну строку, которая может быть передана в качестве аргумента функции, такие как printf()
или strcpy()
или syslog()
,
К сожалению, я не думаю, что это возможно.
Стандарт C11 говорит:
ISO/IEC 9899: 2011 §6.4.2.2 предопределенные идентификаторы
¶1 Идентификатор __func__
должен быть неявно объявляется переводчиком, как если сразу после открывающая скобка каждой функции, декларация
static const char __func__[] = "function-name";
появилось, где function-name - имя лексически-охватывающая функция.
Поэтому __func__
не макро, в отличие от __FILE__
или __LINE__
.
Связанный с этим вопрос What's the difference between __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
? охватывает некоторые альтернативные имена. Это GCC-специфические расширения, а не стандартные имена. Кроме того, в документации GCC 4.8.1 говорится:
Эти идентификаторы не являются макросами препроцессора. В GCC 3.3 и ранее, только в C, __FUNCTION__
и __PRETTY_FUNCTION__
рассматривались как строковые литералы; они могут быть использованы для инициализации массивов символов, и они могут быть объединены с другими строковыми литералами. GCC 3.4 и выше относятся к ним как к переменным, например __func__
. В C++ __FUNCTION__
и __PRETTY_FUNCTION__
всегда были переменными.
Есть веские причины, по которым они не могут быть конструкциями препроцессора. Препроцессор не знает, что такое функция, и является ли текст, который он обрабатывает, входит в область действия функции или то, что является именем закрывающей функции. Это простой текстовый процессор, а не компилятор. Понятно, что можно было бы создать такое понимание в препроцессоре (исключительно для поддержки этой функции), но стандарт не требуется, и стандарт не должен требоваться.
К сожалению, хотя, я думаю, что это означает, что попытки объединить __func__
(любым правописанием) с __FILE__
и __LINE__
в одном макросе для создания одной строки буквальной обречены.
Очевидно, что вы можете создать имя файла и номер строки в виде строки с помощью стандартного механизма макросъемки два этапа:
#define STR(x) #x
#define STRINGIFY(x) STR(x)
#define FILE_LINE __FILE__ ":" STRINGIFY(__LINE__)
Вы не можете получить имя функции в том, что в составе строкового литерала , хоть.
Есть аргументы, что имя файла и номер строки достаточны, чтобы определить, где проблема; имя функции едва ли необходимо. Он более косметический, чем функциональный, и немного помогает программистам, но не другим пользователям.
Используйте переключатель расширителя компилятора, чтобы узнать, что выплевывает. – leppie
Я не верю, что '__func__' - это макрос. Может быть, вы могли бы поместить 'INFO_MSG' в строку формата вместо этого? 'sprintf (buff,« Что-то плохое произошло здесь:% s:% s(), в строке:% d ", __FILE__, __func__, __LINE __);' – tangrs
@leppie: вы можете уточнить? - Что вы подразумеваете под расширителем ?. Кстати, я использую gcc. –