How to check if uint8_t exists as a type, instead of unsigned char?

本秂侑毒 提交于 2019-12-10 17:12:15

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!