Предупреждение о неиспользованном лямбда-захвате, когда фактически используется захват - PullRequest
0 голосов
/ 20 сентября 2018

Этот код:

void foo(int);
int main() {
    const int i = 0;
    auto l = [i](){foo(i);};
}

( godbolt )

Выдает ошибку компилятора при компиляции clang с

-std=c++17 -Werror -Wunused-lambda-capture

Сообщение об ошибке: error: lambda capture 'i' is not required to be captured for this use.

Ошибка правильная: i может быть неявно захвачен здесь, явно захватывать его не нужно.Однако, а) предупреждение имеет неправильное название, поскольку используется i, но предупреждение относится к неиспользованным лямбда-захватам, и б) я просто не хотел бы, чтобы это было ошибкой.Я хочу получить ошибку для фактически неиспользованных лямбда-захватов, но не ошибку для использованных явно захваченных переменных, которые могли быть неявно захвачены.

Есть ли настройка clang, которая делает это?Или я должен устранить ошибку, используя прагма-диагностику push / pop?

1 Ответ

0 голосов
/ 20 сентября 2018

Я думаю, вам здесь не повезло.Если мы рассмотрим обзор, в котором реализована эта функция [Sema] Добавить предупреждение для неиспользованных лямбда-захватов , мы увидим обсуждение того, как заставить замолчать предупреждение, широко обсуждалось.Включая канонический метод лязга, чтобы заставить замолчать неиспользуемое предупреждение, которое приведено к void:

Я думаю, что ожидаемое предупреждение не должно использоваться здесь, поскольку у вас есть (void) fname в лямбде (я не понимаюне получите это предупреждение, если я проверю это локально).

Что работает видеть его вживую , но выглядит глупо для этого случая.

Использование -Wno-unused-lambda-captureно это не лучший вариант для вас:

Я думаю, что патч будет лучше, если вы добавите «-Wno-unused-lambda-capture» к опциям для всех тестов, которыеизменено этим патчем в каталоге CXX /.Это позволит избежать избыточных (void) использований и гарантирует, что использование (void) не будет мешать исходному намерению, когда вещи могут использоваться только в списке захвата.

Исключение переменной иззахват, поскольку он не используется odr, но, как указано, это демонстрирует расхождение реализации, поскольку MSVC не выполняет эту оптимизацию:

Он будет компилироваться без каких-либо предупреждений, если я удалю kDelta из списка захватов.:

#include <stdio.h>

int main(void) {
  const int kDelta = 10000001;
  auto g = [](int i)
           {
             printf("%d\n", i % kDelta);
           };
  g(2);
}

Но тогда компилятор Microsoft C ++ выдаст ошибку:

error C3493: 'kDelta' cannot be implicitly captured because no default capture mode has been specified

Мы можем видеть, что этот случай также работает и действительно удаляет i из захвата действительно исправляет это для clang и gcc, но не для MSVC.

Другое решение, которое будет работать для всех реализаций, - это явный захват [i=i], но, похоже, это также нежелательнорешение ( посмотреть вживую ).

Было бы неплохо, если бы мы могли применить [[Maybe_unused]] здесь, но мы не можем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...