Почему, если (-1 <0) сравнение не удается в c (иногда)?

У меня есть переменная 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 не подписан. Такого не может быть < 0.
wohlstad 03.04.2024 18:57

Тип size_t не имеет знака, поэтому он не может иметь значение -1. Когда вы сравниваете его с -1, фактический -1 преобразуется в беззнаковый.

Eugene Sh. 03.04.2024 18:57

Если вам нужно, чтобы его подписали, используйте вместо этого ssize_t.

Shawn 03.04.2024 18:59

@Shawn ssize_t — это артефакт POSIX, который обычно не доступен.

Andrew Henle 03.04.2024 20:09

@AndrewHenle Наличие POSIX делает его общедоступным.

Shawn 03.04.2024 23:52

@Шон Да, нет

Andrew Henle 04.04.2024 00:07

В чем вообще смысл этого кода? Как файл может иметь отрицательный размер?

Barmar 04.04.2024 10:13

Вот почему size_t не имеет знака: ничто не может иметь отрицательный размер.

Barmar 04.04.2024 10:14
stackoverflow.com/a/2551647/17823490
Emre 04.04.2024 17:22
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
9
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Оба случая связаны с тем, что 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>.

Другие вопросы по теме