D
David Brown
"Rick C. Hodgin" <[email protected]> wrote in message
I thought it was odd too. Obviously just bolting on a set of typedefs
was simpler than adding them properly to the implementation.
You both seem to misunderstand that standards-defined headers, such as
<stdint.h>, /are/ part of the language. They are not "hacks" or
"add-ons" - the C standards say exactly what should and should not be in
<stdint.h>.
Why do you think it matters if int32_t is defined in a header that comes
as part of the toolchain, or if it is built in like "int"? The language
defines the type "int32_t", and says exactly what it should be. You use
it in the same way regardless of how it happens to be implemented.
It is common in C, and in a great many other languages, for features to
be implemented as part of the standard library rather than inside the
compiler itself. This greatly simplifies the implementation, while also
making it easier to make code compatible across different versions of
the language. (When using pre-C99 C, you can write your own int32_t
definitions - if it were built in like "int", you could not do so - or
at least, not as easily.)
And of course, you are both making wildly unsupported assumptions that
the types "int32_t", etc., are defined as typedefs of native types.
First, native types are /not/ variable-sized on any given platform. The
sizes are implementation-dependent - that means that the sizes can vary
between implementation, but within a given implementation, the sizes are
fixed. So the people writing <stdint.h> for any given toolchain know
/exactly/ what size "int", "short", "long", etc., are - and if those
sizes ever change, they change <stdint.h> to match.
Secondly, there is absolutely no requirement that these types be
implemented as typedefs (although obviously that is quite a common
method). The compiler is free to implement them as built-in types
(though it can't treat them as keywords, as it does for "int", "long"
and "short"), or using compiler-specific extensions. As an example, in
avr-gcc they are defined as typedefs but use a compiler-specific
extension rather than plain "int", "short", etc.:
(excerpt from <stdint.h> from avr-gcc-4.5.1)
typedef int int8_t __attribute__((__mode__(__QI__)));
typedef unsigned int uint8_t __attribute__((__mode__(__QI__)));
typedef int int16_t __attribute__ ((__mode__ (__HI__)));
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__)));
typedef int int32_t __attribute__ ((__mode__ (__SI__)));
typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__)));
#if !__USING_MINT8
typedef int int64_t __attribute__((__mode__(__DI__)));
typedef unsigned int uint64_t __attribute__((__mode__(__DI__)));
#endif
The reason this is done is that this particular toolchain supports a
non-standard command-line flag to make "int" 8-bit. It is not often
used, but for some code it is vital to make the object code as small and
fast as possible (the AVR is 8-bit). So the header file uses this
compiler extension which gives exact type sizes.