C Portability – Definition of Portable C

cc99portability

I have been having a huge and heated argument with someone on a slack group – the debate is this :

My argument

  • Portable code is that which compiles with various compilers and runs exactly the same on various architectures without modification.
  • If your code depends on the sizeof(T) of an integral type, in order to keep it portable you should use the types in stdint.h like uint8_t or uint32_t
  • Most non-trivial C programs involve some level of bitwise manipulation, so everyone should know about stdint.h

His argument

  • The C standard says "Use standard types for maximum portability"
  • uint32_t etc. are not guaranteed to be present on all architectures, so don't use any of them
  • stdint.h is C99 so one should avoid it, since embedded systems may only support only C89

My counter is that unless you know the sizes of your types, your code can be fundamentally broken, and even if you do not use stdint.h there is always some header file that has typedefs to explicitly sized types (for example Windows.h declares UINT8, UINT32, DWORD and so on)

The only reply I get is that if you use uint32_t and so on it is not portable according to the C standard. If runtime behaviour changes due to type sizes, that doesn't mean the code is not portable.

Ordinarily I would let this go, but this is in a forum where a lot of budding C and C++ programmers come for guidance, many of whom I know personally. Also this guy claims to be a professional trainer of C programmers, so that worries me all the more.

In what other way can I convince this guy that if you use the basic types like int or short, your code will not be portable?

It boils down to the definition of "portable" – does it merely compile on various compilers, or does it also have to run the same way on every platform it compiles on.

I would have thought runtime portability is what matters – what are your comments?

Best Answer

"Way back when", I had to write highly portable code that needed exact type sizes for a small-device database that ran on anything from 8 bit to 64 bit platforms. We had a coding standard that mandated exact sizes for all variables; this approach made it easier to pass MISRA (among other goodnesses).

To make this work, I wrote and maintained my own "stdint.h" for c89 builds, with the appropriate #ifdef's to use the standard one or "mine".

As for whether using your own stdint.h is "portable", as long as you have appropriate ifdefs, it's about as portable as it can be. Without stdint.h, there are no platform-independent sized types in C, so you "gotta do something". You're right that int, short, etc do NOT have standard sizes in C, and using them is not portable if you're relying on them to be specific sizes.

Related Topic