Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
V1056. The predefined identifier '__fun…
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Cтандарт MISRA
Стандарт AUTOSAR
Дополнительная информация
Оглавление

V1056. The predefined identifier '__func__' always contains the string 'operator()' inside function body of the overloaded 'operator()'.

16 апреля 2020 г.

Анализатор обнаружил использование идентификатора '__func__' в теле перегруженного оператора '()'.

Рассмотрим пример:

class C
{
  void operator()(void)
  {
    std::cout << __func__ << std::endl;
  }
};

void foo()
{
  C c;
  c();
}

При запуске будет выведено 'operator()'. На первый взгляд, это вполне ожидаемое поведение для подобного кода, поэтому перейдем к более неочевидному примеру:

void foo()
{
  auto lambda = [] () { return __func__; };
  std::cout << lambda() << std::endl;
}

Важно учитывать тот факт, что '__func__' не является переменной в привычном смысле этого слова, поэтому следующие варианты не сработают, и по-прежнему будет выведено 'operator()':

void fooRef()
{
  auto lambda = [&] () { return __func__; };
  std::cout << lambda() << std::endl;
}
void fooCopy()
{
  auto lambda = [=] () { return __func__; };
  std::cout << lambda() << std::endl;
}

Чтобы исправить это в случае с лямбдой, необходимо передать '__func__' явно через список захвата:

void foo()
{
  auto lambda = [func = __func__] () { return func; };
  std::cout << lambda() << std::endl;
}

Для более полноценного вывода имени функции даже внутри перегруженного 'operator()' или тела лямбды можно воспользоваться специфичными для платформы/компилятора макросами. Так, компилятор MSVC предоставляет следующие три макроса:

  • '__FUNCTION__' – выводит имя функции, не опуская при этом его область объявления. Например, для лямбды внутри функции main мы получим такой вывод: 'main::<lambda_....>::operator ()';
  • '__FUNCSIG__' – выводит полную сигнатуру функции. Так же может быть полезным в связке с лямбдой: 'auto __cdecl main::<lambda_....>::operator ()(void) const';
  • '__FUNCDNAME__' – выводит декорированное имя функции. Это достаточно специфичная информация, поэтому она не подходит для полноценной замены '__func__'.

Для компиляторов Clang и GCC доступны следующие макросы:

  • '__FUNCTION__' – выводит то же имя, что и стандартный '__func__';
  • '__PRETTY_FUNCTION__' – выводит полную сигнатуру функции, например для лямбды может быть следующий вывод: 'auto main()::(anonymous class)::operator()() const'.
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять