C размер t и ssize t отрицательное значение

size_t объявлен unsigned int поэтому он не может представлять отрицательное значение.
вот тут ssize_t что это подпись типа size_t верно?
Вот моя проблема:

#include <stdio.h>
#include <sys/types.h>

int main(){
size_t a = -25;
ssize_t b = -30;
printf("%zun%zun", a, b);
return 0;
}

почему у меня есть:

18446744073709551591
18446744073709551586

как результат?
Я знаю, что с size_t это может быть возможно, потому что это беззнаковый тип, но почему я получил неправильный результат также с ssize_t??

3 ответов


В первом случае вы присваиваете к типу unsigned - a. Во втором случае вы используете неправильный спецификатор формата. Второй спецификатор должен быть %zd вместо %zu.


прежде всего, вы должны проверить фактический размер двух типов. Что-то вроде следующего фрагмента должно сделать:

#include <stdio.h>
#include <unistd.h>

int main() {
  printf( "sizeof(  size_t ) = %d bytes\n",(int) sizeof( size_t) );
  printf( "sizeof( ssize_t ) = %d bytes\n",(int) sizeof( ssize_t) );
  return 0;
}

Я получаю (64bit Linux, GCC v7.2)" 8 байт " в обоих случаях, что совпадает с long int и long long int, максимальное целочисленное значение CPU-native.

когда размеры одинаковы (и они должны быть всегда), size_t может иметь "2x большие абсолютные значения", чем ssize_t, который, в свою очередь, может иметь знак (это либо положительный, либо отрицательный) ценности.

Если бы они были разными, то больший был бы ... больше и, таким образом, может приспособиться для больших значений.

но, в конце концов, ssize_t и size_t-это два разных типа, используемых для "разговора" о размерах, длинах, объемах памяти и так далее.

первый просто отбрасывает 1 бит для значения, чтобы получить знак, необходимый для сигнала какой-то ошибки.

наконец, эти два типа не взаимозаменяемы, по крайней мере, не всегда. Когда размер может пройти мимо 2^63 байт / элементов разница ясна. реализация не переполнит время будут определены.

при "нормальных" обстоятельствах вы можете бросить от одного к другому. Для случаев, о которых я упоминал ранее, вы никогда не должны смешивать их.

Как ссылка, strlen () и malloc () используют size_t, в то время как read () и readv () используют ssize_t.

таким образом, ssize_t не является подписанной версией size_t, поскольку у них есть неперекрывающиеся области.

затем, чтобы ваши вопросы, две цифры, которые вы видите отличаются на 5 единиц, это exaclty, для чего вы'dexpect. То, что вы видите, - это значение двух переменных thsoe, когда они рассматриваются как "unsigned long". Попробуйте напечатать их как "подписанные длинные" (%ld).


переполнение coz size_t является беззнаковым при попытке установить size_t как (- val) вы получаете переполнение и получаете SIZE_T_MAX-val

например: size_t val = -20; //Вэл == 18446744073709551615 - 20;