Подавить -Wconversion для определенных строк кода

Я использую файл заголовка, который предоставляет встроенные функции. Эти функции не всегда сохраняются в отношении проверки GCC -Wconversion.

Теперь я хочу использовать проверку -Wconversion для моего кода, но хочу подавить предупреждение, которое я получаю для включаемого файла. Изменить: Когда я просто добавляю проверку преобразования в параметры компилятора, я получаю диагностику, а опускание -Wconversion дает мне чистый запуск компилятора.

В соответствии с этим вопросом я окружил включить с некоторыми прагмами:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#include <lpc177x_8x_crc.h>
#pragma GCC diagnostic pop

К сожалению, это не подавляет предупреждения.

warning: conversion to 'int32_t' from 'uint32_t' may change the sign of the result [-Wsign-conversion]

Для простой проверки вы даже можете попробовать это, если у вас нет CMSIS:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
int32_t foo(void)
{
    uint32_t result;
    return result;
}
#pragma GCC diagnostic pop

Аргументы командной строки компилятора:

arm-none-eabi-gcc.exe -mthumb -Wshadow -Winit-self -Wredundant-decls -Wcast-align -Wunreachable-code -W -Wextra -Wall -Wformat=0 -Wconversion -g -O0 -ffunction-sections -fdata-sections -g3 -mcpu=cortex-m3 -c foo.c -o foo.o

Я использую версию arm-none-abi-gcc:

gcc version 4.7.3 20121207 (release) [ARM/embedded-4_7-branch revision 194305] (GNU Tools for ARM Embedded Processors)


person harper    schedule 10.01.2014    source источник
comment
Я пробовал с gcc 4.8 в Linux и не могу воспроизвести эту проблему. Не могли бы вы предоставить точное сообщение, которое вы получаете? Может быть, это какой-то другой, не имеющий ничего общего с -Wconversion?   -  person pentadecagon    schedule 11.01.2014


Ответы (1)


Поскольку в предупреждающем сообщении соответствующий флаг идентифицируется как -Wsign-conversion, вы должны добавить его в прагмы.

#include <stdint.h>
extern int32_t foo(void);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
int32_t foo(void)
{
    uint32_t result = 0;
    return result;
}
#pragma GCC diagnostic pop

Если вы закомментируете второй ignored и скомпилируете с -Wconversion, вы получите ошибку:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -Wconversion -c cvt.c
cvt.c: In function ‘foo’:
cvt.c:9:5: error: conversion to ‘int32_t’ from ‘uint32_t’ may change the sign of the result [-Werror=sign-conversion]
     return result;
     ^
cc1: all warnings being treated as errors
$

Если вы раскомментируете эту прагму, вы не получите ни предупреждений, ни ошибок.

(Проверено на Mac OS X 10.9.1 Mavericks с GCC 4.8.2 — YMMV!) Я отмечаю, что поставляемая Apple clang (версия «Apple LLVM версии 5.0 (clang-500.2.79) (на основе LLVM 3.3svn)») не возражает со второй закомментированной прагмой ignored, с -Wconversion или с -Wsign-conversion, и я попытался разобраться с кодом, передающим параметр uint32_t и назначающим его результат перед его возвратом и т. д. (так что это не просто превосходная оптимизация, признающая, что 0 является особенным, или что возврат неинициализированной переменной является неопределенным поведением и т. д.):

#include <stdint.h>
extern int32_t foo(uint32_t v);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
//#pragma GCC diagnostic ignored "-Wsign-conversion"
int32_t foo(uint32_t v)
{
    uint32_t result = v;
    return result;
}
#pragma GCC diagnostic pop
person Jonathan Leffler    schedule 11.01.2014
comment
Это работает и для моей версии компилятора. Очень странно, что мне нужно отключить больше диагностики (преобразование знака+преобразование), чем я использовал для включения в командной строке (преобразование). - person harper; 11.01.2014
comment
Вчера вечером я не проверял, но сегодня утром достаточно использовать только прагму -Wsign-conversion. Ознакомьтесь с параметрами предупреждений. — будьте осторожны, список не алфавитный. Он описывает -Wconversion и говорит, что -Wno-sign-conversion должен отключить предупреждения о преобразовании целых чисел со знаком в беззнаковое в C (это отключено в C++, если явно не включено). И g++ (4.8.2) не генерирует предупреждений даже с -Wsign-conversion и обеими прагмами в качестве комментариев. - person Jonathan Leffler; 11.01.2014
comment
Согласен, -Wsign-conversion достаточно. Но я был удивлен, что -Wconversion также включает -Wsign-conversion то, что я не включил в командной строке. Теперь я использую #pragma GCC ignored "-Wsign-conversion, чтобы отменить изменение, которое я сделал с параметром командной строки -Wconversion. Странно, но страница, на которую вы ссылаетесь, документирует это. - person harper; 12.01.2014