«сравнение всегда верно из-за предупреждения об ограниченном диапазоне типов данных» в C?

У меня есть следующий код

//Point.h
#define WIDTH 8
#define HEIGHT 8

typedef struct Point
{
  char x;
  char y;
} Point;

//Board.c
#include <stdbool.h>

// Some other functions that we don't care about... 

bool inBounds(Point * p)
{
  return p->x >= 0
    && p->x <= WIDTH
    && p->y >= 0
    && p->y <= HEIGHT;
}

Когда я компилирую это (ppu-gcc 4.1.1), я получаю следующее предупреждение

warning: comparison is always true due to limited range of data type

хотя диапазон char составляет от -127 до 127, а WIDTH равен 8, что находится внутри диапазона char. Я уже пробовал явное приведение WIDTH к символу, но все равно получил ошибку.


person Paul Wicks    schedule 16.04.2009    source источник
comment
просто измените свою структуру на int и посмотрите, что произошло?   -  person Syed Tayyab Ali    schedule 16.04.2009
comment
В вашем случае вам нужно использовать atoi или static cast для x и y, а затем сравнить с высотой и шириной.   -  person Syed Tayyab Ali    schedule 16.04.2009


Ответы (6)


Вы уверены, что char подписан? Попробуйте явно объявить поля как signed char и посмотрите, что получится.

person Dan Breslau    schedule 16.04.2009
comment
Да, я считаю, что char не имеет знака, поэтому сравнение с 0 всегда будет верным. - person Wedge; 16.04.2009
comment
Это зависит от компилятора. Если вам нужно char быть подписанным, вам нужно объявить его подписанным. - person Dan Breslau; 16.04.2009
comment
Да это, исправляет это. Однако строки, в которых я получал ошибку, были строками, в которых я проводил сравнение с положительными числами (ШИРИНА и ВЫСОТА). Странный. - person Paul Wicks; 17.04.2009
comment
Компилятор должен использовать номера строк, начинающиеся с 0 :-) На самом деле у вас может быть другая проблема: использование ‹= и ›= означает, что у вас есть эффективный диапазон WIDTH и HEIGHT, равный 9, а не 8. Если это то, что вы хотите , возможно, вам следует использовать разные имена макросов (MAX_X и MAX_Y?) - person Dan Breslau; 17.04.2009

Я предполагаю, что x >= 0 вызывает предупреждение, потому что char может быть реализовано как unsigned char.

person Daniel Brückner    schedule 16.04.2009

Тип char может быть знаковым или беззнаковым. Это зависит от выбора поставщика вашего компилятора. Может быть даже доступна опция компилятора. Очевидно, что char для вас беззнаковое, поэтому оно всегда больше или равно нулю, и поэтому компилятор предупреждает вас.

Здесь вы используете char для представления «числового типа, занимающего минимум памяти». В этом случае я рекомендую явно использовать signed char или unsigned char. (Каждый из них отличается от обычного char, несмотря на то, что char должен быть либо подписанным, либо беззнаковым.) Зарезервируйте char, когда вы храните символьные данные. Для числовых данных используйте один из двух других типов.

person Rob Kennedy    schedule 16.04.2009
comment
это подтверждается: network-theory.co.uk/docs/gccintro /gccintro_71.html - person dfa; 17.04.2009

Хммм ... разве ваш символ не без знака по умолчанию? В этом случае диапазон будет 0-255, что означает, что ваше сравнение >=0 всегда будет истинным.

person Varkhan    schedule 16.04.2009
comment
Это зависит от платформы и компилятора. Например, GCC на x86 Linux по умолчанию использует знаковые символы, а GCC на PowerPC Linux по умолчанию использует незнаковые символы. - person ephemient; 17.04.2009

Стандарты C и C++ позволяют символьному типу char быть подписанным или беззнаковым, в зависимости от платформы и компилятора. В большинстве систем, включая x86 GNU/Linux и Microsoft Windows, используются знаковые символы, но системы на базе процессоров PowerPC и ARM обычно используют незнаковые символы.(29) Это может привести к неожиданным результатам при переносе программ между платформами, которые имеют разные значения по умолчанию для типа чар.

person Ayeayeron    schedule 07.04.2011

Попробуй это:

typedef struct Point
{
  signed char x;
  signed char y;
} Point;
person Sir Jo Black    schedule 10.04.2015