← Back to context

Comment by adrian_b

13 hours ago

This kind of flexibility is a purely historical thing.

On modern computers, it is impossible to write correct C programs that are agnostic about the true size in bits of the "flexible" types char, short, int, long and long long.

If your program must depend on assumptions about the size in bits of the integer types, those assumptions must be made explicit, by using types like int16_t, int32_t etc.

Writing correct programs that are agnostic about the integer sizes is possible only in programming languages that allow the programmer to install an integer overflow handler even if the CPU does not generate a hardware exception for that, in which case the compiler must insert appropriate overflow checking instructions that would invoke the installed handler when necessary.

This problem did not exist on old computers, where there were hardware exceptions for integer overflows, so even in C you could install a signal handler for SIGFPE, which would also be invoked by integer overflows.

That's not true. All the basic types have minimum sizes, so its perfectly reasonable to write software that stays within those bounds. You can avoid any overflows if you know the minimum limits.

  • If you use the minimum sizes, your program will be very inefficient on most CPUs.

    I have never considered that this is an acceptable solution, which is why in decades of using C, during which I had many times to port programs or even entire real-time operating systems between different ISAs, I have never used those minimum sizes.

    Instead of having those minimum sizes, which I consider useless, C should have had since the beginning, besides sizeof, which gives the size ratio between another type and char, another operator or macro to provide the size in bits of any integer type.

    With that, it would have been possible to use types like short, int or long in a portable way.

    Nowadays, there are _WIDTH, _MAX and _MIN constants for the integer types, but those have been added relatively late to the language, together with the integer types with specified width, for which those constants are superfluous.

    • The _MAX and _MIN, along with CHAR_BIT, was defined for C89 (the first standard for C) 37 years ago, so it was possible to choose the appropriate type. I recall using the C preprocessor to define fixed (or at least, minimum) types for needed values:

          #include <limits.h>
          #if INT_MIN == 32767 && INT_MIN >= 2147483647L
          # error too small
          #else
          # error just right
          #endif
      

      It was C99 (27 years ago) where we got the fixed sized integers. So how do you define "relatively" here?