Tuesday, April 17, 2012

he Standard C Library for Linux, Part Eight: System Properties

The last article was on <string.h> string handling.  This article is on <limits.h> system properites.  These are the sizes of system values that will change depending on what hardware you are operating on or by what the operating system limitations are.  The sizes of integer, char and long are examples of what are defined here.

I am assuming a knowledge of c programming on the part of the reader.  There is no guarantee of accuracy in any of this information nor suitability for any purpose.

The example is rogers_example08.c  This library doesn't have any function calls, it only has defines.  So the example program will print out the  complete list of defines for a system.

As always, if you see an error in my documentation please tell me and I will correct myself in a later document.

I looked in the file /usr/include/limits.h and found the following defines in there and what they mean:

CHAR_BIT     Number of bits in a character.

SCHAR_MIN     Smallest value that a signed character can hold.
SCHAR_MAX    Largest value that a signed character can hold.

UCHAR_MAX    Maximum value an `unsigned char' can hold.

CHAR_MIN    Minimum value that an unsigned character can hold.
CHAR_MAX    Maximum value that an unsigned character can hold.

SHRT_MIN      Maximum value a `signed short int' can hold.
SHRT_MAX     Minimum value a `signed short int' can hold.

USHRT_MAX     Maximum value an `unsigned short int' can hold.

INT_MIN       Minimum value a `signed int' can hold.
INT_MAX      Maximum values a `signed int' can hold.

UINT_MAX      Maximum value an `unsigned int' can hold.

LONG_MAX     Maximum value a `signed long int' can hold. 
LONG_MIN      Minimum value a `signed long int' can hold.

ULONG_MAX    Maximum value an `unsigned long int' can hold.

LLONG_MAX   Maximum value a `signed long long int' can hold.
LLONG_MIN    Minimum value a `signed long long int' can hold.

ULLONG_MAX   Maximum value an `unsigned long long int' can hold.

There also seems to be a lot of other defines that are included in this file from the files /usr/include/bits/posix1_lim.h, /usr/include/bits/posix2_lim.h, and /usr/include/bits/xopen_lim.h, but those are beyond the scope of the Standard C Library, so I am ignoring that issue for now.

Why would you use this?

To take out of context something that is said in the "10 Commandments for C Programmers": `int' and `long' are not the same type. The moment of their equivalence in size and representation is short, and the agony that awaits believers in their interchangeability shall last forever and ever once 64-bit machines become common.

In order to easily port your code to any platform, you don't want to make an assumtion about the size or the max value of any particular type.  You may have selected a certain size for your variable in order to optimize it's use of space.  On some machines, short, int and long are all the same size.  On other machines, short is smaller and int and long are the same size, on other machines short, int and long are 3 different sizes.  Yet other machines have a long long data type.

I have ported programs from 32bit platforms to 64 bit platforms and have ran into many problems with assumptions made about how large int's are and what values an integer or a long can hold.

Horror of horrors is when integers are used to store a pointer on a 32 bit machine.  This simply doesn't work on most 64 bit machines.  On those machines pointers are 8 bytes long and integers are 4 bytes.

Another thing that a lot of people do is store bit flags in an integer or a long. 


The ANSI C Programming Language, Second Edition, Brian W. Kernighan, Dennis M. Ritchie, Printice Hall Software Series, 1988 The Standard C Library, P. J. Plauger, Printice Hall P T R, 1992
The Standard C Library, Parts 1, 2, and 3, Chuck Allison, C/C++ Users Journal, January, February, March 1995
LIMITS(3), BSD MANPAGE, Linux Programmer's Manual,

No comments:

Post a Comment