4

我有两个编译器,一个可以识别 uint8_t(GCC ARM-EABI),另一个不可以(Renesas M16 Standard Toolchain)。

瑞萨工具链不符合 ANSI C,因此您可以丢弃 . 所以 uint8_t, uint16_t,... 没有被定义为现有类型。

为了保持可移植性,我希望有相同的类型(最好是 uint8_t,由于 int 的歧义)。

另外我的平台是不同大小的处理器(ARM 是 32 位,瑞萨是 16 位)。导致 int 是不同的值。

有没有办法检查 uint8_t 是否作为一种类型存在?

如果不是,将它(以及其他 uint16_t、uint32_t、...)声明为一种类型?

4

5 回答 5

11

有没有办法检查 uint8_t 是否作为一种类型存在?

采用:

#include <stdint.h>

#ifdef UINT8_MAX
...
#endif
于 2013-08-08T16:19:07.650 回答
8

uint8_t不是内置类型,它在 stdint.h 中定义。因此,这不是编译器“识别”uint8_t 的问题,而仅仅是使 stdint.h 可用的情况。

如果您的工具链不提供 stdint.h,您可以轻松地提供自己的实现,使用编译器文档来确定与特定大小相对应的内置类型。在没有 stdint.h 的工具链上,您只需向项目提供您自己的工具链,在带有 stdint.h 的工具链上您不需要。这样代码(除了 stdint.h 本身)将在不同平台上相同——您不需要有条件地定义 uint8_t。

您可能遇到的一个问题(例如在某些 TI DSP 上)是内存可能不是 8 位可寻址的,而 char 将是 16 位(或更大)。在这种情况下,uint8_t 或任何 8 位整数类型将根本不受支持。char 始终是特定平台的最小数据类型,但可能大于 8 位。

于 2013-08-08T16:48:10.920 回答
6

有几种不同的方法来处理这个问题。在需要可移植的开源项目中,常见的解决方案是拥有一个“配置脚本”,运行该脚本来设置构建系统。然后它会HAVE_UINTX_TYPES在某些或类似的东西中设置或不设置类似的东西config.h[这是“配置脚本”的结果之一,并执行以下操作:

#include "config.h"
...
#ifndef HAVE_UINTX_TYPES
#include "uintx_types.h"
#endif

在“几乎不需要在任何东西上运行”的系统中,您可以通过简单地将 a-DHAVE_UINTX_TYPES作为编译器标志的一部分来解决相同的问题。并且由于您(可能)有构建系统的某些部分设置不同的编译选项,选择不同的编译器等,因此对于两个不同的构建,这应该不是一个大问题。

假设你很高兴你unsigned char的确实是 8 位,你也可以有一个uintx_types.h包含这样的东西:

typedef unsigned char  uint8_t; 
typedef unsigned short uint16_t;
typedef unsigned long  uint32_t; 

另一种选择是不直接使用uint8_tuint16_t,但有自己的定义[并让这些取决于“是 ARM 还是瑞萨电子”的适当构建设置,例如通过使用不同的包含选项]:

ARM/types.h:

typedef unsigned char  u_int8;
typedef unsigned short u_int16;
typedef unsigned int   u_int32;

瑞萨/types.h:

typedef unsigned char  u_int8;
typedef unsigned int   u_int16;
typedef unsigned long  u_int32;
于 2013-08-08T16:48:06.203 回答
4

如果uint8_t不存在,要么是因为实现不符合 C99,要么是因为它没有满足要求的类型。后者可能意味着CHAR_BIT > 8(这在嵌入式系统之外非常罕见)。

#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

不完全符合 C99 的实现可以提供<stdint.h>uint8_t作为扩展。这很难检测,因为没有条件#include指令;a#include要么包含请求的标头,要么失败。

但是您可以通过使用某种配置脚本在 C 语言之外进行检测。如果编译:

#include <stdint.h>
uint8_t dummy;

那么uint8_t存在;否则它不会。

于 2013-08-08T16:28:32.610 回答
3

的要点uint8_t是,它不会存在于不支持正好 8 位的无符号整数类型的平台上。如果unsigned char可以接受,即使它可能大于 8 位,也不要使用uint8_t. unsigned char在一个平台和另一个平台上使用没有任何好处uint8_t

于 2013-08-08T16:25:03.123 回答