__func__ разница между C и переполнением стека

Действительно ли я прав, что стандарты 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 _ _ [] = «имя-функции
«; было предоставлено, где имя-функции определяется реализацией
строка
. Не указано, имеет ли такая переменная адрес
отличается от любого другого объекта в программе.

И в чем причина этого? Вернуть что-то вроде «Неизвестно», если мы не можем получить текущее имя функции?

8

Решение

Какое «имя» функции в C ++?

  • Это определено его пространством имен?
  • Названы ли перегруженные функции по их типам параметров?
  • Как насчет возвращаемого типа, который не используется для перегрузки?
  • Что происходит в шаблонах функций?
  • Является ли соглашение о вызовах частью имени?
  • Должны ли «const» и «volatile» быть написаны до или после имени типа?

«Строка, определяемая реализацией» дает компилятору некоторую гибкость в том, как он вставляет всю эту информацию в строку. И он отправляет вам, программисту, сообщение о том, что вы не должны пытаться выполнять сравнение или синтаксический анализ строк или фактически делать что-либо, кроме записи значения, если вам нужна переносимость.

(Вы даже не можете сравнить эти значения друг с другом, потому что нет гарантии, что они уникальны. Кажется возможным, что все перегрузки могут привести к одной и той же строке. Поэтому использование ее для составления статистики профилировщика не рекомендуется.)

14

Другие решения

Я подозреваю, что это позволяет компилятору C ++ использовать искаженное имя в __func__,

4

Поскольку 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.

3