преобразование в ‘size_t’ из ‘int’ может изменить знак результата – GCC, C

В моем проекте я включил обработку предупреждений как ошибки и компиляцию с использованием -pedantic и -ansi тегов. Я использую компилятор GCC. В этом проекте я должен использовать сторонний исходный код, который содержит много предупреждений. Поскольку я отношусь к предупреждениям как к ошибкам, у меня есть трудное время для исправления их кода.

Большинство предупреждений касаются недействительного преобразования из int в size_t или наоборот. В некоторых случаях я не смогу сделать оба переменные одинаковыми, я имею в виду, что я не смогу что-то изменить в size_t . В таких случаях я делаю явное приведение. Что-то вроде,

 size_t a = (size_t) atoi(val); 

Мне интересно, это правильный подход? Есть ли какие-либо проблемы при выполнении подобных действий?

Если эти предупреждения незначительны, могу ли я подавить их только в своих файлах? Как мне сделать то же самое на MSVC?

Редактировать:

Кастинг – это единственный подход, если вы хотите заблокировать компилятор на один экземпляр портативным способом. Это прекрасно, если вы знаете, что делаете, например, что вы можете гарантировать, что результат atoi никогда не будет отрицательным.

В GCC вы можете отключить все предупреждения преобразования знака с помощью -Wno-sign-conversion . Существует также -Wno-sign-compare (для таких вещей, как 2u > 1 ), но это не будет актуально, если вы не используете -Wextra .

Вы также можете использовать диагностические прагмы, например

 #pragma GCC diagnostic ignored "-Wsign-conversion" 

В MSVC существует несколько предупреждений, относящихся к несоответствию подписанного / неподписанного, например:

  • Уровень 4:
    • C4389 , C4245 , C4365
  • Уровень 3:
    • C4018 ( 2u > 1 )
  • Уровень 2:
    • C4267 ( size_tint )

Чтобы отключить предупреждение в MSVC, вы можете добавить #pragma warning например

 #pragma warning (disable : 4267) 

или добавьте флаг /wd4267 в параметры компилятора.


Возможно, вам следует использовать strtoul вместо atoi .

 size_t a = strtoul(val, NULL, 0); 

(Предупреждение отсутствует только в том случае, если size_t имеет size_t как unsigned long . На большинстве платформ это верно, но это не гарантируется.)

Преимущество заключается в том, что вы можете выполнить проверку ошибок с помощью этой функции, например

 #include  #include  int main () { char val[256]; fgets(val, 256, stdin); char* endptr; size_t a = strtoul(val, &endptr, 0); if (val == endptr) { printf("Not a number\n"); } else { printf("The value is %zu\n", a); } return 0; } 

Взгляните на вики OpenOffice на лучшие практики для безошибочного кода: http://wiki.services.openoffice.org/wiki/Writing_warning-free_code

Они предлагают статические приведения для этих преобразований, а затем предоставляют прагму для отключения предупреждений для определенного раздела кода.

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

С другой стороны, я действительно презираю [явные] броски. Предложение использовать strtoul вместо atoi , вероятно, очень хорошее. Я вижу, что вы прокомментировали, что atoi был всего лишь примером, но в принципе применяется тот же принцип: используйте функции, которые возвращают нужный вам тип, а не заставляют другой тип в нужный вам тип. Если функция является той, которую вы написали, а не библиотечной функцией, это может означать только исправление ваших функций для возврата size_t для размеров, а не для int .