<p>I've worked on a number of different embedded systems.  They have all used <code>typedef</code>s (or <code>#defines</code>) for types such as <code>UINT32</code>.</p>

<p>This is a good technique as it drives home the size of the type to the programmer and makes you more conscious of chances for overflow etc.</p>

<p>But on some systems you know that the compiler and processor won't change for the life of the project.</p>

<p>So what should influence your decision to create and enforce project-specific types?</p>

<p>EDIT
I think I managed to lose the gist of my question, and maybe it's really two.</p>

<p>With embedded programming you may need types of specific size for interfaces and also to cope with restricted resources such as RAM.  This can't be avoided, but you can choose to use the basic types from the compiler.</p>

<p>For everything else the types have less importance.<br>
You need to be careful not to cause overflow and may need to watch out for register and stack usage.  Which may lead you to <code>UINT16</code>, <code>UCHAR</code>.
Using types such as <code>UCHAR</code> can add compiler 'fluff' however.  Because registers are typically larger, some compilers may add code to force the result into the type.<br>
<PRE>i++;</PRE>
can become
<PRE>ADD REG,1
AND REG, 0xFF</PRE>
which is unecessary.</p>

<p>So I think my question should have been :-</p>

<p>given the constraints of embedded software what is the best policy to set for a project which will have many people working on it - not all of whom will be of the same level of experience.</p>

[{'answer_id': 7091, 'author': 'Zooba', 'author_id': 891, 'author_profile': 'https://Stackoverflow.com/users/891', 'pm_score': 1, 'selected': False, 'text': '<p>Consistency, convenience and readability. "UINT32" is much more readable and writeable than "unsigned long long", which is the equivalent for some systems.</p>\n\n<p>Also, the compiler and processor may be fixed for the life of a project, but the code from that project may find new life in another project. In this case, having consistent data types is very convenient.</p>\n'}, {'answer_id': 7117, 'author': 'Chris Hanson', 'author_id': 714, 'author_profile': 'https://Stackoverflow.com/users/714', 'pm_score': 3, 'selected': False, 'text': '<p>The C99 standard has a number of standard sized-integer types.  If you can use a compiler that supports C99 (gcc does), you\'ll find these in <code>&lt;stdint.h&gt;</code> and you can just use them in your projects.</p>\n\n<p>Also, it can be especially important in embedded projects to use types as a sort of "safety net" for things like unit conversions.  If you can use C++, I understand that there are some "unit" libraries out there that let you work in physical units that are defined by the C++ type system (via templates) that are compiled as operations on the underlying scalar types.  For example, these libraries won\'t let you add a <code>distance_t</code> to a <code>mass_t</code> because the units don\'t line up; you\'ll actually get a compiler error.</p>\n\n<p>Even if you can\'t work in C++ or another language that lets you write code that way, you can at least use the C type system to help you catch errors like that by eye.  (That was actually the original intent of Simonyi\'s Hungarian notation.)  Just because the compiler won\'t yell at you for adding a <code>meter_t</code> to a <code>gram_t</code> doesn\'t mean you shouldn\'t use types like that.  Code reviews will be much more productive at discovering unit errors then.</p>\n'}, {'answer_id': 7515, 'author': 'Bernard', 'author_id': 61, 'author_profile': 'https://Stackoverflow.com/users/61', 'pm_score': 2, 'selected': False, 'text': "<p>My opinion is if you are depending on a minimum/maximum/specific size <strong>don't</strong> just assume that (say) an <code>unsigned int</code> is 32 bytes - use <code>uint32_t</code> instead (assuming your compiler supports C99).</p>\n"}, {'answer_id': 13858, 'author': 'Yossi Kreinin', 'author_id': 1648, 'author_profile': 'https://Stackoverflow.com/users/1648', 'pm_score': 5, 'selected': True, 'text': '<p>I use type abstraction very rarely. Here are my arguments, sorted in increasing order of subjectivity:</p>\n\n<ol>\n<li><p>Local variables are different from struct members and arrays in the sense that you want them to fit in a register. On a 32b/64b target, a local <code>int16_t</code> can make code slower compared to a local int since the compiler will have to add operations to /force/ overflow according to the semantics of <code>int16_t</code>. While C99 defines an <code>intfast_t</code> typedef, AFAIK a plain int will fit in a register just as well, and it sure is a shorter name.</p></li>\n<li><p>Organizations which like these typedefs almost invariably end up with several of them (<code>INT32, int32_t, INT32_T</code>, ad infinitum). Organizations using built-in types are thus better off, in a way, having just one set of names. I wish people used the typedefs from stdint.h or windows.h or anything existing; and when a target doesn\'t have that .h file, how hard is it to add one?</p></li>\n<li><p>The typedefs can theoretically aid portability, but I, for one, never gained a thing from them. Is there a useful system you can port from a 32b target to a 16b one? Is there a 16b system that isn\'t trivial to port to a 32b target? Moreover, if most vars are ints, you\'ll actually gain something from the 32 bits on the new target, but if they are <code>int16_t</code>, you won\'t. And the places which are hard to port tend to require manual inspection anyway; before you try a port, you don\'t know where they are. Now, if someone thinks it\'s so easy to port things if you have typedefs all over the place - when time comes to port, which happens to few systems, write a script converting all names in the code base. This should work according to the "no manual inspection required" logic, and it postpones the effort to the point in time where it actually gives benefit.</p></li>\n<li><p>Now if portability may be a theoretical benefit of the typedefs, <i>readability</i> sure goes down the drain. Just look at stdint.h: <code>{int,uint}{max,fast,least}{8,16,32,64}_t</code>. Lots of types. A program has lots of variables; is it really that easy to understand which need to be <code>int_fast16_t</code> and which need to be <code>uint_least32_t</code>? How many times are we silently converting between them, making them entirely pointless? (I particularly like BOOL/Bool/eBool/boolean/bool/int conversions. Every program written by an orderly organization mandating typedefs is littered with that).</p></li>\n<li><p>Of course in C++ we could make the type system more strict, by wrapping numbers in template class instantiations with overloaded operators and stuff. This means that you\'ll now get error messages of the form "class Number&lt;int,Least,32&gt; has no operator+ overload for argument of type class Number&lt;unsigned long long,Fast,64&gt;, candidates are..." I don\'t call this "readability", either. Your chances of implementing these wrapper classes correctly are microscopic, and most of the time you\'ll wait for the innumerable template instantiations to compile.</p></li>\n</ol>\n'}, {'answer_id': 18066, 'author': 'Ben Combee', 'author_id': 1323, 'author_profile': 'https://Stackoverflow.com/users/1323', 'pm_score': 2, 'selected': False, 'text': '<p>I like using stdint.h types for defining system APIs specifically because they explicitly say how large items are.  Back in the old days of Palm OS, the system APIs were defined using a bunch of wishy-washy types like "Word" and "SWord" that were inherited from very classic Mac OS.  They did a cleanup to instead say Int16 and it made the API easier for newcomers to understand, especially with the weird 16-bit pointer issues on that system.  When they were designing Palm OS Cobalt, they changed those names again to match stdint.h\'s names, making it even more clear and reducing the amount of typedefs they had to manage.</p>\n'}, {'answer_id': 25095, 'author': 'TK.', 'author_id': 1816, 'author_profile': 'https://Stackoverflow.com/users/1816', 'pm_score': 2, 'selected': False, 'text': "<p>I believe that MISRA standards suggest (require?) the use of typedefs.</p>\n\n<p>From a personal perspective, using typedefs leaves no confusion as to the size (in bits / bytes) of certain types. I have seen lead developers attempt both ways of developing by using standard types e.g. int and using custom types e.g. UINT32.</p>\n\n<p>If the code isn't portable there is little <em>real</em> benefit in using typedefs, <em>however</em> , if like me then you work on both types of software (portable and fixed environment) then it can be useful to keep a standard and use the cutomised types. At the very least like you say, the programmer is then very much aware of how much memory they are using. Another factor to consider is how 'sure' are you that the code will not be ported to another environment? Ive seen processor specific code have to be translated as a hardware engieer has suddenly had to change a board, this is not a nice situation to be in but due to the custom typedefs it could have been a lot worse!</p>\n"}, {'answer_id': 3481884, 'author': 'supercat', 'author_id': 363751, 'author_profile': 'https://Stackoverflow.com/users/363751', 'pm_score': 0, 'selected': False, 'text': '<p>Maybe I\'m weird, but I use ub, ui, ul, sb, si, and sl for my integer types.  Perhaps the "i" for 16 bits seems a bit dated, but I like the look of ui/si better than uw/sw.</p>\n'}, {'answer_id': 30762430, 'author': 'ollo', 'author_id': 1622894, 'author_profile': 'https://Stackoverflow.com/users/1622894', 'pm_score': 1, 'selected': False, 'text': '<p>If your embedded systems is somehow a <strong><em>safety critical system</em></strong> (or similar), it\'s strongly <em>advised</em> (if not required) to use typedefs over plain types.</p>\n\n<p>As <em>TK.</em> has said before, <strong>MISRA-C</strong> has an (advisory) rule to do so:</p>\n\n<blockquote>\n  <p><strong>Rule 6.3 (advisory):</strong>   typedefs that indicate size and signedness should be used in place of the basic numerical types.</p>\n</blockquote>\n\n<p><em>(from MISRA-C 2004; it\'s Rule #13 (adv) of MISRA-C 1998)</em></p>\n\n<hr>\n\n<p>Same also applies to C++ in this area; eg. <a href="http://www.stroustrup.com/JSF-AV-rules.pdf" rel="nofollow">JSF C++ coding standards</a>:</p>\n\n<blockquote>\n  <p><strong>AV Rule 209</strong> A  UniversalTypes  file will be created to define all sta\n  ndard types for developers to use. The  types include: [uint16, int16, uint32_t etc.]</p>\n</blockquote>\n'}, {'answer_id': 37919751, 'author': 'Pelle', 'author_id': 1549060, 'author_profile': 'https://Stackoverflow.com/users/1549060', 'pm_score': 1, 'selected': False, 'text': '<p>Using <code>&lt;stdint.h&gt;</code> makes your code more portable for unit testing on a pc. </p>\n\n<p>It can bite you pretty hard when you have tests for everything but it still breaks on your target system because an <code>int</code> is suddenly only 16 bit long.</p>\n'}]
['https://Stackoverflow.com/questions/7084', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/888/']