У меня есть переменная size_t file_size;
, объявленная в моем файле c, которая будет присвоена -1
позже, а затем, когда я это сделаю
if (file_size < 0) {
// do something
} else {
printf("C is confusing\n");
}
output: C is confusing
но если я установлю свое условие на
if (file_size == -1) {
printf("C is easy\n");
} else {
// do something
}
output: C is easy
Может кто-нибудь объяснить, почему существует хотя бы малая вероятность того, что это может произойти. Заранее спасибо!
Тип size_t
не имеет знака, поэтому он не может иметь значение -1
. Когда вы сравниваете его с -1
, фактический -1
преобразуется в беззнаковый.
Если вам нужно, чтобы его подписали, используйте вместо этого ssize_t
.
@Shawn ssize_t
— это артефакт POSIX, который обычно не доступен.
@AndrewHenle Наличие POSIX делает его общедоступным.
@Шон Да, нет
В чем вообще смысл этого кода? Как файл может иметь отрицательный размер?
Вот почему size_t
не имеет знака: ничто не может иметь отрицательный размер.
Оба случая связаны с тем, что size_t является беззнаковым, т. е. может представлять только неотрицательные значения.
Когда вы присваиваете ему -1
, вы фактически получаете его беззнаковый эквивалент (побитовый). Поскольку большинство (если не практически все) систем используют дополнение до двух для представления отрицательных целых чисел, вы получите значение, в котором все биты равны 1
. Например, в системах, где size_t
является 32-битным, ему будет присвоено значение 0xFFFFFFFF (32 1
в двоичном формате).
1-й случай:
Поскольку это unsigned
, этого никогда не может быть < 0
.
Второй случай:
Когда вы сравниваете его с -1
, -1
фактически преобразуется в беззнаковое значение (все 1
в двоичном формате, как описано выше), и тогда равенство становится возможным.
В системе POSIX (или аналогичной), если вы хотите правильно представлять отрицательные значения, вы можете использовать ssize_t
вместо size_t
(это подписанная версия).
Для этого требуется #include <sys/types.h>
.
size_t
не подписан. Такого не может быть< 0
.