Избегайте лишних предупреждений при компиляции кода 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 "Построить среду"

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

3 ответа

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

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

или же

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

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

#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 мне пришлось дважды запускать препроцессор, чтобы он работал. Не могу сказать, нужно ли то же самое для лязга.

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

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

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

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

Другие вопросы по тегам