Search code examples
clibcc89

Stdint.h in ANSI C (C89)


I have recently become interested in switching from writing C99 code to writing plain ANSI C (C89), as the new features in the language are not worth the extreme portability and reliability of writing it in ANSI C. One of the biggest features I thought I would miss making the transition from C99 to C89 would be the stdint.h standard library file; or so I thought. According to this site, there is no stdint.h file in the C89 standard, which is also what I found on Wikipedia. I wanted to make sure that this was indeed the case, so I wrote a minimal test program that I expected would not compile when providing the flags -ansi and -pedantic-errors in both GCC and Clang;

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

int main(void)
{
    printf("The size of an int8_t is %ld.\n",  sizeof(int8_t));
    printf("The size of an int16_t is %ld.\n", sizeof(int16_t));
    printf("The size of an int32_t is %ld.\n", sizeof(int32_t));
    printf("The size of an int64_t is %ld.\n", sizeof(int64_t));

    printf("The size of a uint8_t is %ld.\n",  sizeof(uint8_t));
    printf("The size of a uint16_t is %ld.\n", sizeof(uint16_t));
    printf("The size of a uint32_t is %ld.\n", sizeof(uint32_t));
    printf("The size of a uint64_t is %ld.\n", sizeof(uint64_t));

    return 0;
}

However, what I found was not a compiler error, nor a warning, but a program that compiled! Since it worked just as well on either compiler, I'm under the assumption that this is not a bug in the compiler. The output, for reference, was what one would expect for a working C99 implementation:

The size of an int8_t is 1.
The size of an int16_t is 2.
The size of an int32_t is 4.
The size of an int64_t is 8.
The size of a uint8_t is 1.
The size of a uint16_t is 2.
The size of a uint32_t is 4.
The size of a uint64_t is 8.

I have a few questions about this "feature".

  • Should I be able to rely upon a stdint.h header being provided for a C89 program?
  • If not, what steps would I have to take in creating a header that functions the same as stdint.h?
  • How did programmers, in the time before C99, solve this problem of having reliable sizes for integers in their programs in a platform-agnostic manor?

Solution

  • Should I be able to rely upon a stdint.h header being provided for a C89 program?

    No. You said you picked C89 for portability reasons and then the first thing you reach for is non-portable extensions...

    If not, what steps would I have to take in creating a header that functions the same as stdint.h?

    How did programmers, in the time before C99, solve this problem of having reliable sizes for integers in their programs in a platform-agnostic manor?

    With a forest of macros like for example in this answer. If C89, you typedef all the names present in stdint.h for the given platform. Otherwise, if standard C, you just include stdint.h.

    So you'll need your own "notstdint.h" which contains all of this and then you have to port it to each system where integer sizes are different. And yes, this makes C89 less portable than standard C.