Can I trust sizeof(size_t) <= sizeof(unsigned long int) is always true?

别说谁变了你拦得住时间么 提交于 2019-12-11 09:17:17

问题


Can I trust sizeof(size_t) <= sizeof(unsigned long int) is always true, according to C89 standard?

i.e., I will not loos value if I use a unsigned long where size_t is expected and vice-versa.


回答1:


Perhaps the best explanation of what happens with size_t and integer types in C89 is the rationale document of it. Read carefully the section 3.4.4 of this document:

Sizeof and size_t for C89 (rationale)

The 3rd paragraph says that:

The type of sizeof, whatever it is, is published (in the library header ) as size_t, since it is useful for the programmer to be able to refer to this type. This requirement implicitly restricts size_t to be a synonym for an existing unsigned integer type, thus quashing any notion that the largest declarable object might be too big to span even with an unsigned long.

This means that, for the concern of C89, in general size_t is the same as a preexisting unsigned integer type, what in C89 implies one of the unsigned char, unsigned short, unsigned int, unsigned long.
In particular, every value of type size_t is in the range of unsigned long.
By reading the specifications of the standard C89, you can see also that sizeof(size_t)<=sizeof(long).


Now, the situation in C99 is a little different. This standard says that:

  1. 7.17 par. 2 size_t is an unsigned integer type.
  2. 7.17 par. 4 The types used for size_t [...] should not have an integer conversion rank greater than that of signed long int
  3. --------- unless the implementation supports objects large enough to make this necessary.
  4. 6.2.5 par. 8 For any two integer types with the same signedness and different integer conversion rank (see 6.3.1.1), the range of values of the type with smaller integer conversion rank is a subrange of the values of the other type.

    Since the integer conversion rank of signed long int is the same that unsigned long int, this implies that the range of values of size_t is contained in the range of values of unsigned long int. But the item 3 in the list above left the door open to exceptions to this rule.

So, we can only say that is highly intended that an implementation makes the values of size_t hold in the range of the unsigned long int. But we cannot be completely sure.

If you want to be sure, you can do the following procedure to check your system:

  1. Include the files <limits.h> and <stdint.h> in order to access the information about integer types for your implementation.
  2. Compare the constants ULONG_MAX (from <limits.h>) and SIZE_MAX (from <stdint.h>).

A short program would be this:

 #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;
 }



回答2:


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).

So sizeof(size_t) <= sizeof(unsigned long int) is true, but sizeof(size_t) > sizeof(unsigned long int) is not true and can lead to data loss. For instance:

size_t a = b;

may cause data loss if b is an unsigned long int since its value can be grater than an size_t can hold.



来源:https://stackoverflow.com/questions/19329860/can-i-trust-sizeofsize-t-sizeofunsigned-long-int-is-always-true

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!