преобразование в «size_t» из «int» может изменить знак результата - GCC, C - PullRequest
4 голосов
/ 31 июля 2010

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

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

size_t a = (size_t) atoi(val);

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

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

Ответы [ 3 ]

7 голосов
/ 31 июля 2010

Edit:

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

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

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

#pragma GCC diagnostic ignored "-Wsign-conversion"

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

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

#pragma warning (disable : 4267)

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


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

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

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

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

#include <stdlib.h>
#include <stdio.h>

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;
}
4 голосов
/ 31 июля 2010

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

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

0 голосов
/ 31 июля 2010

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

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

...