2

在 C 语言中,使用相同的源代码来定位不同的处理器架构是很常见的(或者至少是可能的)。处理器架构以不同方式定义整数大小也很常见。为了增加代码可移植性并避免整数大小限制,建议使用 C 标准整数标头。但是,我对这实际上是如何实现的感到困惑。

如果我正在编写一个为 x86 编写的小 C 程序,然后决定将其移植到 8 位微控制器上,那么微控制器编译器如何知道如何将 'uint32_t' 转换为其本机整数类型?

编写 C 编译器时是否有一些映射要求?例如,如果您的编译器要与 C99 兼容,您是否需要一个映射功能,将所有 uint32_t 替换为本机类型?

谢谢!

4

3 回答 3

2

通常<stdint.h>包含相当于

typedef int int32_t;
typedef unsigned uint32_t;

具有适合当前机器的实际类型选择。

实际上,它通常比这要复杂得多,有许多额外的辅助头文件和辅助预处理器宏,但效果是一样的:像这样的名称uint32_t最终是真正的类型名称,就像由typedef.

你问“如果你的编译器要兼容 C99,你需要一个映射功能吗?”,答案基本上是“是”,但“映射功能”可以只是编译器编写者在其分布式中选择的特定类型的副本stdint.h。(要回答您的另一个问题,是的,那里的副本至少与<stdint.h>编译器的数量一样多;没有一个主副本或任何东西。)

一边评论。您说,“为了增加代码可移植性并避免整数大小限制,建议使用 C 标准整数头”。真正的建议是当您有特殊要求时使用该标题,例如对于具有精确类型的尺寸。如果由于某种原因你需要一个有符号的类型,比如说,正好是 32 位,那么一定要使用int32_tfrom stdint.h。但大多数时候,你会发现“普通”类型喜欢int并且long非常好。请不要让任何人告诉您必须为您声明的每个变量选择一个确切的大小,并使用类型名称 frostdint.h来声明它。

于 2016-11-05T14:40:50.433 回答
2

不同架构的处理很可能通过条件预处理指令来实现,例如#ifor #ifdef。例如,在 GNU/Linux 平台上,它可能看起来像:

# if __WORDSIZE == 64
typedef long int        int64_t;
# else
__extension__
typedef long long int       int64_t;
# endif
于 2016-11-05T14:45:05.160 回答
0

没有魔法发生,以“映射”或“翻译”的形式:stdint.h只包含一个typedef语句列表。区别在于代码生成器,而不是编译器前端。

对于 8 位目标,代码生成器将使用本机指令对其本机支持的任何类型进行算术运算(可能有 16 位加法指令)。对于其余部分,它将插入对库例程的调用以实现更大的数据类型。

8 位编译器的 RTL 包含“long_add”、“long_subtract”等例程并不少见。

于 2016-11-05T14:41:21.797 回答