Есть ли опция командной строки gcc, чтобы отключить предупреждение: передача аргумента n отбрасывает квалификаторы из типа - PullRequest
3 голосов
/ 25 февраля 2011

Я пытаюсь скомпилировать -Wall -Werror, и это мешает моему стилю.

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

P.S. Я в основном делал это, чтобы попытаться прояснить, что некоторые переменные являются константами, это хороший или плохой стиль c, когда вы работаете с библиотечными функциями, которые не используют const?

Ответы [ 3 ]

1 голос
/ 25 февраля 2011

Используйте переключатель -Wno-ignored-qualifiers.

Иногда, при компиляции с -Wall -Wextra -Werror (как я тоже, потому что это очень хорошая практика ), вы сталкиваетесь с повторяющимися предупреждениями о том, что вы можете захотеть отключить широкий проект или поИсходный файл базы.Например, я часто отключаю в своих проектах -Wno-long-long.Это неплохая практика, потому что вы знаете, что делаете, и не хотите контролировать сторонний код.

Как я понимаю, вы пытаетесь отключить предупреждение для определенных частей кода., так как в противном случае это разрушит ваши усилия, поставив const везде.В этом случае выполните:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-qualifiers"

OffendingThirdPartyFunction(MyConstParam);

#pragma GCC diagnostic pop

или также (не проверено, я не знаю, где поставить точку с запятой, и у меня нет рабочего GCC здесь на работе)

#define NO_WARNING(expr)                                        \
    _Pragma("GCC diagnostic push")                              \
    _Pragma("GCC diagnostic ignored \"-Wignored-qualifiers\"")  \
    expr                                                        \
    _Pragma("GCC diagnostic pop")

NO_WARNING(OffendingThirdPartyFunction(MyConstParam));

Кроме того, вы можете использовать приведение.Это, безусловно, самое портативное решение.

OffendingThirdPartyFunction((param_t*)MyConstParam);
1 голос
/ 25 февраля 2011

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

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

Не злоупотребляйте этой привилегией, иначе вы будете арестованы полицией кодекса и приговорены к 9 месяцам общественного кодирования в Аде. Это вылечит вас от того, что вы снова будете жаловаться на предупреждения С.

0 голосов
/ 25 февраля 2011

Не используйте параметр командной строки: предупреждение говорит о том, что ваш код не является const-safe.Правильно, ваш код не const-safe, хотя это вина любого, кто написал библиотеку, которую вы используете.

Если вы отключите предупреждения, вы их не получитебольше, даже если вы пишете небезопасный код, и он является вашей ошибкой.

Вместо этого всякий раз, когда одна из библиотечных функций принимает указатель на non-const, но гарантирует не изменятьссылку на указатель, затем отбросьте константу от вашего указателя и передайте ее.Приведение служит записью в коде, который вы (программист) утверждаете, что ничего недействительного не произойдет, даже если система типов не может этого доказать и, вероятно, должна быть прокомментирована.

Например:

// in this library
void print_int(int *p) { printf("%d\n", *p); }
void set_int(int *p) { *p = 6; }

// your code
const int n = 5;
print_int((int*)(&n)); // warning suppressed for this call only,
                       // having carefully checked the print_int docs.

// further down your code
set_int(&n); // You *want* the compiler to stop this!

Или, если вас это беспокоит (потому что у вас много таких вызовов), напишите обертки для нарушающих функции библиотеки:

void print_int_const(const int *p) { print_int((int*)(p)); }
// but no wrapper for set_int

Помните, что приведение также удаляет volatile (и вообще принимает много неверных вводов).Перегрузка предотвращает случайное использование совершенно неправильного типа, в то время как приведение на месте - нет.

...