Избегайте лишних предупреждений при компиляции кода Qt с помощью ccache / clang

У меня та же проблема, что и этот парень.
Компилируя clang и ccache, я получаю это предупреждение каждый раз, когда он встречает Q_OBJECT:

warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign]

Это происходит только при использовании ccache, компиляция того же кода с использованием одного только clang работает нормально.

Кажется, есть аналогичная проблема с расширениями макросов где предлагаемое решение состоит в том, чтобы установить переменную среды

CCACHE_CPP2=yes

К сожалению, это, похоже, не решает мою проблему, или, возможно, я делаю это неправильно.

Я пытался:

  • Сборка из командной строки с

    • CCACHE_CPP2=yes ninja

    • export CCACHE_CPP2=yes
      ninja

  • Сборка из Qt Creator, добавление CCACHE_CPP2 «Построить среду»

Что еще я могу сделать, чтобы исправить эту проблему расширения макроса? Я специально не хочу отключать предупреждения глобально (потому что это плохо) или локально (потому что это означает оборачивание всех макросов в шаблон для конкретного компилятора).

8

Решение

Попробуйте добавить -Wno-self-assignment для флагов CPP. Это должно позволить вам отключить ошибки самостоятельного назначения:

CXXFLAGS= $(CXXFLAGS) -Wno-self-assign

или же

CPPFLAGS=$(CPPFLAGS) -Wno-self-assign
3

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

Простите, что у меня нет лязга, чтобы проверить это, но я чувствовал, что должен все равно помочь. Расширяя ответ Марека, есть возможность разместить прагму внутри другого макроразложения. Это очень уродливое решение, но таким образом вам нужно определить макрос только один раз, вместо того, чтобы создавать прагмы по всей вашей кодовой базе.

#define WARN int&x = x;

#define NO_WARN _Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \
WARN \
_Pragma("GCC diagnostic pop")

int main(){
NO_WARN
}

Как вы можете видеть, я протестировал его с помощью gcc (у ​​меня нет средств для тестирования с помощью clang), но в clang это должно работать нормально, заменив «GCC» на «clang» внутри макроса (и используя -Wself_assign). Применение к вашей проблеме (псевдокод):

#ifdef clang
#define MY_Q_OBJECT _Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wself-assign\"") \
Q_OBJECT \
_Pragma("clang diagnostic pop")
#else
#define MY_Q_OBJECT Q_OBJECT
#endif
class A{
MY_Q_OBJECT // Unfortunately you still need to replace Q_OBJECT on your classes
}

Еще один уродливый недостаток в том, что, по крайней мере на gcc, мне пришлось дважды запускать препроцессор, чтобы он работал. Не могу сказать, нужно ли то же самое для лязга.

3

Игнорирование этого предупреждения в глобальном масштабе не является проблемой. Он предупреждает о фиктивном коде, а не о возможных логических ошибках, вызванных опечаткой. Вот почему я проголосовал за ответ @MichaelCMS.

Но есть способ отключить предупреждение только часть кода:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-assign"Q_OBJECT
#pragma clang diagnostic pop

Это должно сработать (если я не испортил название флага), но мне это не нравится, с большим количеством макросов котельной пластины.

1