问题
I have two compilers, one that recognizes uint8_t(GCC ARM-EABI), and one that doesn't(Renesas M16 Standard Toolchain).
The Renesas Toolchain is NOT ANSI C compliant, so you can throw out . So uint8_t, uint16_t,... aren't defined as existing types.
In order to maintain portability, I would like to have the same types(preferably uint8_t, due to the ambiguity of int).
Also my platforms are different size processors(ARM is 32 bit, and Renesas is 16 bit). Causing int to be different values.
Is there a way to check if uint8_t exists as a type?
And if not, declare it(and others uint16_t, uint32_t,...) as a type?
回答1:
There are a few different ways to deal with this. In an open source project that needs to be portable, the common solution is to have a "configure script", which is run to setup the build system. It would then have something like HAVE_UINTX_TYPES
that is set or not set in some config.h
or similar [which was one of the results of the "configure script", and do something like this:
#include "config.h"
...
#ifndef HAVE_UINTX_TYPES
#include "uintx_types.h"
#endif
In a less "needs to run on almost anything" system, you could solve the same problem by simply have a -DHAVE_UINTX_TYPES
as part of the flags to the compiler. And since you (presumably) have some part of the build system that sets different compile options, picks a different compiler, etc, for the two different builds, this shouldn't be a big issue to add.
And assuming that you are happy that your unsigned char
is indeed 8 bits, you could also do have a uintx_types.h
that contains something like this:
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
Another option is to not use uint8_t
and uint16_t
etc directly, but have your own definitions [and have these depend on the appropriate build setting for "is it ARM or Renesas", e.g. by using different include options]:
ARM/types.h:
typedef unsigned char u_int8;
typedef unsigned short u_int16;
typedef unsigned int u_int32;
Renesas/types.h:
typedef unsigned char u_int8;
typedef unsigned int u_int16;
typedef unsigned long u_int32;
回答2:
Is there a way to check if uint8_t exists as a type?
Use:
#include <stdint.h>
#ifdef UINT8_MAX
...
#endif
回答3:
uint8_t
is not a built-in type, it is defined in stdint.h. So it is not a matter of the compiler "recognising" uint8_t, but rather simply a case of making stdint.h available.
If your toolchain does not provide stdint.h, you can easily provide your own implementation, using the compiler documentation to determine the built-in types that correspond to the specific sizes. On the toolchain without stdint.h you simply provide your own to the project, on the toolchain with stdint.h you don't. That way the code (other than stdint.h itself) will be identical across platforms - you don't need to conditionally define uint8_t.
One problem you may come across (on some TI DSP's for example) is that memory may not be 8 bit addressable and a char will be 16 bit (or larger). In that case uint8_t or indeed any 8 bit integer type will not be supported at all. A char is always the smallest data type for the specific platform, but may be larger than 8 bit.
回答4:
The main point of uint8_t
is that it won't exist on platforms that don't support an unsigned integral type with exactly 8 bits. If unsigned char
is acceptable, even though it might be larger than 8 bits, then don't use uint8_t
. There's nothing to be gained by using unsigned char
on one platform and uint8_t
on another.
回答5:
If uint8_t
doesn't exist, it's either because the implementation does not conform to C99, or because it has no type that meets the requirements. The latter probably means CHAR_BIT > 8
(which is vanishingly rare outside embedded systems).
#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
#ifdef UINT8_MAX
// uint8_t exists
#else
// uint8_t doesn't exist in <stdint.h>
#else
// uint8_t probably doesn't exist because this isn't a C99 or better compiler
#endif
It's possible for an implementation that doesn't fully conform to C99 to provide <stdint.h>
and uint8_t
as an extension. That's difficult to detect, because there's no conditional #include
directive; a #include
either includes the requested header or fails.
But you can detect it by going outside the C language, using some kind of configuration script. If this compiles:
#include <stdint.h>
uint8_t dummy;
then uint8_t
exists; otherwise it doesn't.
来源:https://stackoverflow.com/questions/18131032/how-to-check-if-uint8-t-exists-as-a-type-instead-of-unsigned-char