Действительно ли я прав, что стандарты C гарантируют, что значение _ _ func _ _ всегда является именем включающей функции, тогда как в C ++ (я имею в виду C ++ 11, конечно) это может быть любая строка, определяемая реализацией (например, если у нас есть функция foo без параметров, мы можем получить что-то вроде «Некоторая строка fdgdg asdfs fsdf sd»)?
ISO / IEC 9899: 2011
6.4.2.2 Предопределенные идентификаторы
Семантика
1 Идентификатор _ _ func _ _ должен быть неявно объявлен
переводчик как будто, сразу после открывающей скобки каждого
определение функции, объявление static const char _ FUNC знак равно
«Имя-функции»; появился, где имя-функции — это имя
лексически заключающая в себе функция.
ISO / IEC 14882: 2011
8.4.1 В целом [dcl.fct.def.general]
8 Предопределенная переменная локальной функции _ _ func _ _ определяется как
определение формы static const char _ _ func _ _ [] = «имя-функции
«; было предоставлено, где имя-функции определяется реализацией
строка. Не указано, имеет ли такая переменная адрес
отличается от любого другого объекта в программе.
И в чем причина этого? Вернуть что-то вроде «Неизвестно», если мы не можем получить текущее имя функции?
Какое «имя» функции в C ++?
«Строка, определяемая реализацией» дает компилятору некоторую гибкость в том, как он вставляет всю эту информацию в строку. И он отправляет вам, программисту, сообщение о том, что вы не должны пытаться выполнять сравнение или синтаксический анализ строк или фактически делать что-либо, кроме записи значения, если вам нужна переносимость.
(Вы даже не можете сравнить эти значения друг с другом, потому что нет гарантии, что они уникальны. Кажется возможным, что все перегрузки могут привести к одной и той же строке. Поэтому использование ее для составления статистики профилировщика не рекомендуется.)
Я подозреваю, что это позволяет компилятору C ++ использовать искаженное имя в __func__
,
Поскольку C ++ допускает перегрузку функций в зависимости от типа их параметров, и поскольку функции могут быть размещены в неглобальной области (обе из которых не допускаются в стандарте C), простого имени функции, заключающей в себе лексическое выражение, недостаточно идентифицировать это.
Например, рассмотрим:
class A {
public:
A() {
std::cout << __func__ << std::endl;
}
void funca() {
std::cout << __func__ << std::endl;
}
};
int main() {
A a;
a.funca();
}
Что это должно напечатать?
GCC создаст программу, которая печатает «A» и «funca», но стандарт разрешает ему печатать «A :: A» и «a :: funca», что не допускается стандартом C.