2013-10-12 4 views

ответ

3

Возможно, лучшее объяснение того, что происходит с size_t и целыми типами в C89 является обоснованным документом. Внимательно прочитайте раздел 3.4.4 этого документа:

Sizeof and size_t for C89 (rationale)

3-й пункт гласит, что:

Тип SizeOf бы это ни было, публикуется (в библиотеке заголовка) как size_t, так как это полезно для программиста , чтобы иметь возможность обратиться к этому типу. Это требование неявно ограничивает size_t как синоним существующего целого числа без знака , тем самым аннулируя любое представление о том, что наибольший декларируемый объект может быть слишком большим, чтобы охватить даже с длиной без знака.

Это означает, что для беспокойства C89, в общем size_t является такой же, как существовавшие ранее типа unsigned целого, то, что в C89 предполагает один из unsigned char, unsigned short, unsigned int, unsigned long.
В частности, каждое значение типа size_t находится в диапазоне unsigned long.
Считая спецификации стандарта C89, вы также можете увидеть, что sizeof(size_t)<=sizeof(long).


Сейчас ситуация в C99 немного отличается. Этот стандарт гласит, что:

  1. 7.17 пар. 2 size_t - целочисленный тип без знака.
  2. 7.17 пар. 4 Типы, используемые для size_t [...], не должны иметь целочисленный показатель ранга, отличный от целого числа, чем signed long int
  3. --------- если реализация не поддерживает объекты, достаточно большие, чтобы сделать это необходимым.
  4. 6.2.5 пар. 8 Для любых двух целых типов с одинаковой степенью соответствия и разного целочисленного преобразования (см. 6.3.1.1) диапазон значений типа с меньшим числом ранга преобразования является поддиапазоном значений другого типа.

    Поскольку преобразования ранга целочисленного из signed long int то же самое, что unsigned long int, это означает, что диапазон значений size_t содержится в диапазоне значений unsigned long int. Но элемент 3 в приведенном выше списке оставил дверь открытой для исключений из этого правила.

Таким образом, мы можем только сказать, что это весьма Подразумевается, что реализация делает значения size_t удержания в диапазоне unsigned long int. Но мы не можем быть полностью уверены.

Если вы хотите быть уверены, что вы можете сделать следующую процедуру, чтобы проверить вашу систему:

  1. Включить файлы <limits.h> и <stdint.h> для того, чтобы получить доступ к информации о целочисленных типов для реализации.
  2. Сравнить константы ULONG_MAX (от <limits.h>) и SIZE_MAX (от <stdint.h>).

Короткая программа будет следующим образом:

#include <stdio.h> 
#include <limits.h> 
#include <stdint.h> 

int main(void) { 
     printf("Is the range of size_t containd in that of unsigned long?\n\n"); 
     if (SIZE_MAX <= ULONG_MAX) 
      printf("Yes"); 
     else 
      printf("No"); 
     return 0; 
} 
1

According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3).

Так sizeof(size_t) <= sizeof(unsigned long int) верно, но sizeof(size_t) > sizeof(unsigned long int) это не так, и может привести к потере данных. Например:

size_t a = b; 

может привести к потере данных, если b является unsigned long int, поскольку его значение может быть терки, чем size_t может держать.

+0

+1 хорошо сказал ... – chux

+3

Ваш ответ кажется двусмысленным, потому что ваш утверждают 'SizeOf (size_t) <= SizeOf (неподписанный долгий INT)' означает что 'izeof (size_t)> sizeof (unsigned long int)' всегда false, но вы подразумеваете, что «возможно true». Кроме того, Маска спросила о ** C89 ** стандарте, а не ** C89 **. – pablo1977

+0

Исправление: "а не ** C99 **" – pablo1977

Смежные вопросы