Почему поле st_size в структуре stat подписано?

st_size определяется как off_t.

off_t определяется как подписанный целочисленный тип.

Почему st_size определяется как подписанный тип? Может ли это быть отрицательным? Что это означает, если он отрицательный?

Ответ 1

Лучшая причина, по которой я могу думать, - не вводить неподписанную версию off_t в качестве дополнительного типа; POSIX уже имеет смехотворное изобилие целочисленных типов с аналогичным использованием.

Кроме того, возможность хранения -1 в st_size, когда размер не является концепцией, которая имеет смысл, вероятно, полезна; Я не уверен, что какие-либо реализации делают это, и я не могу найти, где POSIX устанавливает любые требования к содержимому st_size, за исключением обычных файлов и символических ссылок...

Ответ 2

off_t определяет смещения в файле, который может быть равен размеру файла, но также может быть отрицательным, например, если вы ищете назад.

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

Ответ 3

В правилах продвижения C, выражения, сочетающие разные типы подписанных типов, будут вести себя одинаково арифметически корректно, независимо от соответствующих размеров при условии, что ни один из промежуточных вычислений не будет переполнен. Однако добавление неподписанных типов сделает поведение кода намного более зависимым от целочисленных размеров.

Дано:

int test_size(off_t x, long y, long long z)
{
  return x-y > z;
}

Если off_t были неподписанными, то в зависимости от его размера он мог бы заставить y получить продвигается до unsigned long, с вычислением, выполненным по этому типу, который затем получает повышение до signed long long и сравнивается с z с использованием подписанного сравнения, или это может привести к тому, что z получит повышение до unsigned long long, в котором случайное сравнение будет сделано без подписи. Также было бы возможно (хотя и не обязательно), что off_t может быть достаточно маленьким (и/или long достаточно большим), что y вычитается с использованием подписанной арифметики.

Количества, которые могут быть достаточно большими, чтобы требовать что-то как минимум равное int, даже если они никогда не будут отрицательными, обычно должны быть представлены беззнаковыми типами, только если есть основания полагать, что они не будут вписываться в конкретный подписанный тип, но, безусловно, будет соответствовать его неподписанному аналогу. Такие ситуации не очень распространены, но существуют с size_t на 16-битных системах (было невозможно архитектурно невозможно, чтобы один объект превышал 64K, но объекты более 32K были обычным делом). Такой сценарий будет казаться менее привлекательным в интерфейсе файловой системы (если 32-разрядной подписки недостаточно, 32-разрядный без знака, вероятно, не будет достаточно даже очень долго).

Ответ 4

Я думаю, что некоторая функция fseek в POSIX должна принимать отрицательный результат как смещение.

Ответ 5

off_t используется для обработки смещений файлов во многих функциях. Некоторые функции используют специальное значение -1 (например, lseek это говорит о том, что произошла ошибка). Многие другие типы данных подписаны в UNIX для размещения значений -1 (например, time_t).