Як вимкнути попередження для окремих файлів включення?


79

Я хотів би відключити певні попередження для всіх файлів, які включені, прямо чи опосередковано, до конкретних файлів із включенням. Наприклад, я хочу відключити попередження "ви призначаєте строковий літерал символу *", для всіх файлів або файлів, включених до файлів, включених до #include <bar/*>(зірка в моєму випадку означає "тут може бути що завгодно").

Причина в тому, що деякі люди, з якими мені доводиться програмувати, просто не можуть використовувати "const", тому врешті-решт я отримую багато попереджень щодо конкретного зловживання буквального рядка. Я хотів би ігнорувати ті тисячі попереджень, що надходять від їх коду, щоб я міг зосередитися на помилках у власному коді та виправити їх.

Я використовую Intel C ++ та GCC. Деякі мої приятелі використовують дзвін, тому я був би радий почути рішення і для цього.



Я розумію це правильно - якщо файл, про який йде мова, включений <bar/the_file.h>, попередження слід придушити, а з <the_file.h>ні?
Xeo

@Neil дякую за відповідні посилання. Тільки для того, щоб пояснити іншим, які можуть мати певні небажані асоціації: Наведені вище два посилання не є дурними посиланнями!
Йоханнес Шауб - літб

@Xeo не те, що зокрема. Я можу жити з усіма попередженнями, які вимкнуто для цього файлу. Він не повинен мати конкретний шаблон включення. Я підозрюю, що те, як я сформулював своє запитання, трохи невдале.
Йоханнес Шауб - літб

Який компілятор ви використовуєте? (Методи придушення попереджень часто різняться залежно від компілятора.)
Бен Хокінг

Відповіді:


71

При використанні GCC ви можете використовувати -isystemпрапор замість -Iпрапора, щоб вимкнути попередження з цього місця.

Отже, якщо ви зараз використовуєте

gcc -Iparent/path/of/bar …

використання

gcc -isystem parent/path/of/bar …

замість цього. На жаль, це не особливо дрібний контроль. Мені не відомий більш цілеспрямований механізм.


4
у clang є --system-header-prefix = option, див. clang.llvm.org/docs/…
dev_null

50

Краще рішення GCC: використовуйте #pragma.

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-W<evil-option>"
#include <evil_file>
#pragma GCC diagnostic pop

наприклад:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <QtXmlPatterns>
#pragma GCC diagnostic pop

Це не те, що я хочу. Я шукаю спосіб вимкнути попередження для всіх файлів, які починаються з "Qt" (на вашому прикладі. Не лише для одного іменованого файлу. Ми вже використовуємо діагностичний push / pop, але, на жаль, це не може збігати символи підстановки з іменами файлів наскільки ми бачили.
Йоганнес Шауб - літ

Вибачте, я неправильно зрозумів. AFAIK, у вас є лише два варіанти: створити файл заголовка, який включає всі заголовки, про які йдеться, загорнуті в діагностику #pragma, і включити його спочатку (і розраховуйте на те, що охоронці мульти-включення обробляють файли лише один раз). Або розгляньте заголовки як системні заголовки з -isystem. Я не думаю, що існує спосіб визначити власні діагностичні правила, засновані на шляху включення (крім поведінки isystem.). Я завжди використовував підхід "створити" include_all_bar.h "файл" до цієї проблеми.
Бред

13
Треба сказати, що, хоча ця відповідь не є голосовою, я вважаю її дуже корисною. Незважаючи на те, що він не зовсім відповідає вихідному питанню (усі бібліотеки у шляху / префіксі), він надає спосіб вибіркового виключення деяких попереджень для даного набору заголовків. 👍
benschumacher

36

Коли я використовую g++та маю заголовки сторонніх виробників, які генерують безліч попереджень із моїми звичайними значеннями -Wall -Wextra& co. Я прагну згрупувати їх в окремі включення, вказавши .system_header #pragma

[...] GCC надає код, який міститься в заголовках системи, спеціальним режимом. Усі попередження, крім попереджень #warning(див. Діагностику), припиняються, поки GCC обробляє заголовок системи. Макроси, визначені в заголовку системи, не захищені від кількох попереджень, де б вони не розгорталися. Цей імунітет надається спеціально, коли ми виявляємо, що попередження генерує багато помилкових спрацьовувань через код у макросах, визначених у заголовках системи.

[...]

Існує також директива, #pragma GCC system_headerяка говорить GCC врахувати решту поточного файлу include системним заголовком, незалежно від того, де його було знайдено. Код, який надходить до #pragmaфайлу, не вплине. #pragma GCC system_headerне впливає на первинний вихідний файл.

Я віддаю перевагу цьому рішенню, -isystemаніж тому, що воно більш дрібне, і я можу помістити його безпосередньо у джерела, не надто возившись з аргументами командного рядка та включаючи каталоги.

Приклад з огидною кореневою бібліотекою:

#ifndef ROOTHEADERS_HPP_INCLUDED
#define ROOTHEADERS_HPP_INCLUDED
#ifdef __GNUC__
// Avoid tons of warnings with root code
#pragma GCC system_header
#endif
#include "TH1F.h"
#include "TApplication.h"
#include "TGraph.h"
#include "TGraph2D.h"
#include "TCanvas.h"
#endif

2
Ох, дуже добре. +1 ... на жаль, такі файли, як правило, з’являються раніше, ніж інші файли-включення, і застосування прагми, схоже, впливає на решту файлів, тобто всі наступні файли включають.
Конрад Рудольф

@ Конрад Рудольф: Ви впевнені в цьому? хіба це не лише для одного включення та його суб-включень?
Амір Заде

1
@Green Так, це я мав на увазі. Тим не менше, це вимагає від мене або помістити всі сумнівні включення в кінець списку включень (і, як я вже говорив, це часто не бажано або навіть можливо), або помістити всі сумнівні включення в окремий заголовок, який ви потім включите. Це також не ідеальний варіант у великому спільному проекті.
Конрад Рудольф

2
@Konrad: друге рішення - це рішення, яке я прийняв.
Matteo Italia

0

Я думаю, найпростішим рішенням було б написати простий скрипт, який викликатиме компілятор, компілювати та видаляти небажані результати на основі імені файлу та типу попередження. Ви можете використовувати різні сценарії для кожного компілятора.

Просто оновіть свій файл make, щоб використовувати цей скрипт, а не безпосередньо викликати компілятор.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.