在C中,通常(或至少可能)使用相同的源代码来定位不同的处理器体系结构。处理器体系结构通常以不同方式定义整数大小。为了增加代码可移植性并避免整数大小限制,建议使用C标准整数标头。但是,我对这实际是如何实现感到困惑。
如果我写了一个为x86编写的小程序,然后决定将其移植到8位微控制器上,那么微控制器编译器如何知道如何将'uint32_t'转换为其原生整数类型?
编写C编译器时是否有一些映射要求?如果您的编译器要兼容C99,您需要有一个映射功能,用本机类型替换所有uint32_t吗?
谢谢!
答案 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
。但大多数情况下,您会发现像int
和long
这样的“普通”类型完全没问题。请不要告诉任何人您必须为您声明的每个变量选择一个确切的大小,并使用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”等例程并不罕见。