Избегайте лишних предупреждений при компиляции кода 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
Это должно сработать (если я не испортил название флага), но мне это не нравится, с большим количеством макросов котельной пластины.