title: Integer and boolean types to use in an embedded system with two architectures
body: <p>I'm writing some software for an embedded system, mostly in C. It happens to be a dual core TI platform and I am using a few vendor and other libraries. The processor has one ARM core which is 32-bit and can do byte access (<code>sizeof(char) == 1</code> and <code>sizeof(int) == 4</code>: 8 and 32 bits respectively) and one C28 core which is a 32-bit CPU with <code>sizeof(char) == sizeof(int) == 1</code>: both are 16-bits (<a href="http://processors.wiki.ti.com/index.php/Byte_Accesses_with_the_C28x_CPU#Byte_Accesses_With_the_C28x_Compiler" rel="nofollow noreferrer">yes, really</a>).</p>
  
  <p>I plan to avoid types such as <code>int</code> and <code>char</code> in favour of always being explicit about what I am doing. I would plan on this anyway, but doubly so when "char" is a bit traitorous and not always 8 bits.</p>
  
  <p>However, I have quite a few sets of integer and booleans definitions (and floats, but let's not worry about them) available to me, depending on exactly how many and which headers I include:</p>
  
  <p>On the ARM side:</p>
  
  <pre><code>&lt;stdint.h&gt; // from the ARM compiler's include dir
  typedef   signed char   int8_t;
  typedef unsigned char  uint8_t;
  typedef          short  int16_t;
  typedef unsigned short uint16_t;
  typedef          int    int32_t;
  typedef unsigned int   uint32_t;
  typedef          long long  int64_t;
  typedef unsigned long long uint64_t;
  </code></pre>
  
  <p>On the C28 Side:</p>
  
  <pre><code>&lt;stdint.h&gt; // from the C28 compiler's include dir
  typedef          int    int16_t;
  typedef unsigned int   uint16_t;
  typedef          long   int32_t;
  typedef unsigned long  uint32_t;
  // note: no uint8_t
  </code></pre>
  
  <p>On both sides:</p>
  
  <pre><code>// "DSP28_DATA_TYPES" - comes with the following comment:
      // For Portability, User Is Recommended To Use Following Data Type Size
      // Definitions For 16-bit and 32-Bit Signed/Unsigned Integers:
  typedef int int16;
  typedef long int32;
  typedef long long int64;
  typedef unsigned long long Uint64;
  
  &lt;xcd/std.h&gt; // "TI_STD_TYPE", also with and xdc_ prefix, presumably for internal use to the XDC framework
  typedef int Int;
  typedef unsigned Uns;
  typedef char Char;
  typedef unsigned long Uint32;
  typedef unsigned int Uint16;
  typedef unsigned char Uint8;
  typedef long Int32;
  typedef int Int16;
  typedef char Int8;
  </code></pre>
  
  <p>There are also a handful of library-specific versions, such as </p>
  
  <pre><code>typedef char          INT8; // from the NDK network headers
  typedef unsigned char u8_t;  // from the uIP network headers
  </code></pre>
  
  <p>As for booleans, I have</p>
  
  <pre><code>&lt;stdbool.h&gt; // on ARM
  &lt;stdbool.h&gt; // on C28
  typedef unsigned char bool;
  
  &lt;xdc/std.h&gt; // on both
  typedef unsigned short  Bool;       /* boolean flag */
  
  // TI Driver library
  typedef unsigned char tBoolean;
  
  // TI Flash access library
  typedef unsigned char       boolean;
  </code></pre>
  
  <p>My gut instinct is to go with <code>&lt;stdint.h&gt;</code> and <code>&lt;stdbool.h&gt;</code> on both sides. This will have the side effect that any headers that I <em>do</em> share between the ARM and C28 core can't use <code>uint8_t</code>. However, this IPC code is very limited and easily dealt with.</p>
  
  <p>On code that runs on only one core, it means I don't need to pull in TI or library headers in cases like this:</p>
  
  <pre><code>// someheader_arm.h
  #include &lt;stdint.h&gt; // only need a standard header, not a TI one
  #include &lt;stdbool.h&gt;
  
  extern uint8_t getDeviceFooIndex(void);
  extern bool    isDeviceFoobared(void);
  </code></pre>
  
  <p>Which then means I can include like this and prevent forcing the user of the header to have some library header included first, or force visibility of it by adding the library include to my header:</p>
  
  <pre><code>// someimpl_arm.c
  #include "someheader_arm.h" // include first of all to ensure that all types are visible to the headers
  #include &lt;some_ti_lib.h&gt; // brings in UintN, for example
  
  // main.c
  #include "someheader_arm.h" 
  #include &lt;some_ti_lib.h&gt; // e.g. needed by main.c functions
  // include order doesn't matter - UintN isn't needed by someheader_arm.h
  </code></pre>
  
  <p>There are places when function signatures for library functions take <code>unsigned long</code> style or <code>UintN</code> style, but it's always fairly clear what's going to what. The main concern is keeping headers like the example above and variables throughout <em>my</em> code tidy and consistent, even if the functions I call from libraries use an exciting range of definitions.</p>
  
  <p>The fact that things like <code>char</code> and <code>int</code> differ radically on the two cores is an interesting quirk, but my question would stand even on a single core processor, I just have even more types floating around than usual!</p>
  
  <p>So the question is: Does it make sense to make the C99 standard headers a general standard in the code and generally disregard the various types provided in libraries?</p>