2010-07-27 133 views
5

int类型的变量被称为“一个机器类型的字长” 但在嵌入式系统中,8位微的C编译器使用16位int(8位无符号字符),然后获取更多位, INT行为正常: 在16位微位int也是16位,并在32位微位int是32位等。有没有标准的方法来检测硬件的位宽?

那么,有没有一个标准的方式来测试它,像BITSIZEOF(INT)?

像“sizeof”是为字节,但为位。

,这是我的第一个想法

register c=1;     
    int bitwidth=0; 
    do 
    { 

     bitwidth++; 

    }while(c<<=1); 

    printf("Register bit width is : %d",bitwidth); 

但是这需要C作为int和它的8个编译器是常见的INT 16位使用,所以它给了我16的结果,似乎也没有标准使用“int”作为“注册宽度”,(或不尊重)

为什么我要检测它?假设我需要许多变量,它们需要少于256个值,因此它们可以是8,16,32位,但是使用正确的大小(与内存和寄存器相同)会加快速度并节省内存,如果不能在代码决定,我必须重新编写函数为每建筑

编辑阅读答案 后,我发现这个好文章

http://embeddedgurus.com/stack-overflow/category/efficient-cc/page/4/

我引用的结论(加粗体)

因此 的底线是这样的。如果你想 开始编写高效的,便携的 嵌入代码,你应该采取的第一步是开始使用C99 数据类型'最少'和'快'。如果您的 编译器不符合C99,则 抱怨,直到它或 - 更改 供应商。如果您进行此更改I 认为您将会惊喜 您的代码大小和 速度将得到改进。

+2

使用像char,int,short这样的类型是不好的做法,应该被嵌入式系统禁止。我见过一个编译器(CodeWarrior),它允许你改变每种类型的长度。只要使用types.h头文件即可。 – kmalmur 2010-07-27 17:59:15

回答

17

我不得不重新编写函数为每建筑

不,你不会。使用C99的stdint.h,其类型如,这将是一种能够保存256个值的类型,并且很快。

然后,无论平台如何,类型都会相应地改变,并且您不会更改代码中的任何内容。如果您的平台没有定义这些集合,您可以添加自己的。

远胜于重写每个函数。

+0

+1这是一个解决方案和更多的标准,我认为(无论如何,我仍然无法检测硬件的宽度) – 2010-07-27 17:55:25

+1

@赫尔南:毫不奇怪。 C不关心实现,宽度是需要使用某些特定于操作系统的API暴露的事情。 – GManNickG 2010-07-27 18:00:51

+0

Codewarrior编译器似乎不符合C99,我将遵循embeddedgurus.com的建议,抱怨或改变供应商= P – 2010-07-27 19:13:02

1

您编译的ISA在编译器运行时已经知道,所以最好的选择是在编译时检测它。根据你的环境,你可以使用从autoconf/automake风格的东西到更低级别的所有东西#ifdef来调整你的代码到它将要运行的特定架构。

+1

复杂的方式。按照Paul和Andrey的建议,使用'sizeof(int)* CHAR_BIT'。 – sbi 2010-07-27 17:44:07

7
#include <limits.h> 

const int bitwidth = sizeof(int) * CHAR_BIT; 
+1

-1'int'的宽度不是OP正在寻找的内容... – 2012-03-20 05:40:48

1

我完全不明白你的意思是“没有使用任何STANDAR‘诠释’为‘注册宽度’,在原来的C语言规范(C89/90)的类型int是隐含在在没有明确类型的情况下,你的register c相当于register int c,这在C89/90中是完全标准的。还要注意C语言规范要求类型int支持至少-32767 ... + 32767范围,这意味着任何平台int将至少有16个值形成位。

至于位宽...sizeof(int) * CHAR_BIT会给你int类型的对象表示中的位数。

理论上,int类型的值表示不保证使用其对象表示的所有位。如果您需要确定用于值表示的位数,则可以简单地分析INT_MININT_MAX值。

P.S.看看你的问题的标题,我怀疑你真正需要的只是CHAR_BIT的价值。

+0

问题是,在16位或8位体系结构中,CHAR_BIT,INT_MIN和INT_MAX具有相同的值,因此我无法将其用于检测,至少在大多数常用的微量控制器编译器中。我认为int的标准是从16位开始的 – 2010-07-27 17:42:01

+0

@Hernán:你是说在这些架构上使用'CHAR_BIT == INT_MIN == INT_MAX'吗?这是荒谬的!确定任何类型“T”的比特数的标准符合方式是“sizeof(T)* CHAR_BIT”。 – sbi 2010-07-27 17:46:21

+0

@sbi,它们在这个意义上有相同的值,CHAR_BIT(8位)= CHAR_BIT(16位),INT_MIN(8位)= INT_MIN(16位)等等。 – 2010-07-27 17:51:45

0

请问unsigned charunsigned short是否符合您的需求?为什么不使用它?如果没有,你应该使用编译时间标志来引入适当的代码。

+0

转换为/从默认机器字大小时会有开销,所以使用尽可能小的变量不是最好的方式 – 2010-07-28 12:31:40

7

更直接地回答你的更深层次的问题,如果你有需要一种可以跨平台移植非常具体的存储大小,你应该使用类似 types.h stdint.h定义与位数指定的存储类型。

例如,uint32_t总是无符号的32位,而int8_t总是带有8位的符号。

+0

+1这是一个解决方案(无论如何,我仍然无法检测到硬件的宽度) – 2010-07-27 17:54:51

+0

Isn'那么'unint32_t'是最少_32位? ICBWT。 – sbi 2010-07-27 18:09:39

+1

@sbi:它们在手册页中称为精确宽度整数。但是我提到了不正确的头文件。它不是types.h,而是stdint.h。我正在纠正答案。 – 2010-07-27 18:17:35

0

我认为在这种情况下,您不需要知道您的架构有多少位。如果你想优化你的代码,只要尽可能小就使用变量。

+0

鉴于问题的最后一段,我认为这是一条路。如果所有值都小于256,则使用'uint8_t'。当您的CPU将其复制到一个寄存器中时,它将根据需要对其进行签名扩展以填充寄存器的其余部分。对于使用小于寄存器大小的数字,您应该看不到性能损失。你最好的选择是使用'stdint.h'中最小的数据类型来代表你所有的值。 – bta 2010-07-27 18:17:58

+0

也许,但我想无符号字符是最便携的答案,只是因为stdint.h是从C99,而不是在以前 – 2010-07-27 18:55:24

相关问题