如何在编译期间翻译<stdint.h>的标准整数?

时间:2016-11-05 14:28:44

标签: c stdint cstdint

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

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

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

谢谢!

3 个答案:

答案 0 :(得分:2)

通常<stdint.h>包含等效的

typedef int int32_t;
typedef unsigned uint32_t;

使用适合当前机器的实际类型选择。

实际上它通常要复杂得多,有多个额外的辅助头文件和辅助预处理器宏,但效果是一样的:像uint32_t之类的名称最终成为真正的类型名称,就好像由typedef定义。

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

一方评论。您说,“为了增加代码可移植性并避免整数大小限制,建议使用C标准整数标头”。真正的建议是,当您有特殊要求时,例如对于具有确切类型的尺寸,您可以使用该标题。如果由于某种原因您需要签名类型,比方说,正好是32位,那么请务必使用int32_t中的stdint.h。但大多数情况下,您会发现像intlong这样的“普通”类型完全没问题。请不要告诉任何人您必须为您声明的每个变量选择一个确切的大小,并使用stdint.h的类型名称来声明它。

答案 1 :(得分:2)

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

# if __WORDSIZE == 64
typedef long int        int64_t;
# else
__extension__
typedef long long int       int64_t;
# endif

答案 2 :(得分:0)

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

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

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