Choosing the most suitable integer size / range to use for variables

stdint.h in C99 contains many options for integer sizes, types and ranges - so many I donโ€™t know which ones to choose!

I know how to use size_t and ptrdiff_t when necessary, and I use fixed size types for storage and transmission. My question is about values โ€‹โ€‹that will only be stored in the memory of the host machine.

For example, the image structure may contain the following elements:

 struct image { integer width, height; /* pixel dimensions of the image */ integer bits_per_pixel; ... }; 

If width and height never exceed SHRT_MAX , should I use short or stick with int ? Image cannot have negative width or height, so use an unsigned type? Perhaps (u)int_least16_t right choice? Something else?

If bits_per_pixel will never exceed 64, use char , unsigned char , uint8_t , int or something else?

What would you use in this example and why?

How does the processor architecture on which the code will run affect the choice? i.e. PPC or x86, 32 or 64 bit.
How does the device on which the code will work affect the choice? i.e. desktop, phone, console.
How does the choice depend on performance and optimization?

My question is in simple terms: how do you choose which integer to use?

+6
c c99 integer size
source share
4 answers

I would say: do not worry about this, it is often a form of premature optimization. But my rules of thumb are:

  • Use a regular int possible. This should be the actual word size of the machine.
  • Use unsigned types when you need a well-defined integer overflow.
  • Use type (u)intX_t when you need a view with two additions.
  • Use unsigned char for large arrays with values <= UCHAR_MAX .

Beware that many types in <stdint.h> are optional, so you cannot depend on their existence. POSIX does it a little better.

+4
source share

In your example, I would just use int or (perhaps better) unsigned for all three fields. It makes no sense to use smaller types, except for an array that will contain thousands or millions of elements; it just imposes artificial restrictions.

To answer a more general question, here are some guidelines that I follow:

  • Always choose the correct signature for the values โ€‹โ€‹that you will keep.
  • To count objects, indices, line / data lengths in memory, etc. use size_t .
  • For data that has a specific range of values โ€‹โ€‹that you need to store, and where you never need to store values โ€‹โ€‹outside the range, use one of the fixed-size integers from stdint.h ( uint8_t , uint16_t , uint32_t , etc.). Common examples of these kinds of needs that come to mind are pixel values, sound samples, and Unicode characters (usually 8, 16, and 32 bits, respectively).
  • Otherwise, int or unsigned is probably suitable for use.
+3
source share

There are no hard and fast rules.

If you choose a type that is too small, you can end up artificially restricting the data sets that your program can process. Too big and your performance may suffer.

Unless you run into performance issues for your specific task, I definitely tend to be "too big." Although using an integer for bits / pixels is kind of dumb, it probably won't hurt anything in a larger scheme of things.

+1
source share

If your application is really memory intensive, don't worry about the size and use of int. Using short or char can cause subtle errors that can cause problems later. In addition, using char or short will not give you any extra processor cycles.

+1
source share

All Articles