代码之家  ›  专栏  ›  技术社区  ›  Craig McQueen Dr. Watson

什么平台有8位char之外的东西?

  •  128
  • Craig McQueen Dr. Watson  · 技术社区  · 15 年前

    偶尔,有人会指出 char (aka 'byte') isn't necessarily 8 bits .

    好像是8位的 烧焦 几乎是普遍的。我本以为主流平台需要8位 烧焦 以确保其在市场上的生存能力。

    无论是现在还是过去,什么平台使用 烧焦 这不是8位,为什么它们与“正常”8位不同?

    在编写代码和考虑跨平台支持(例如,对于通用库)时,对于非8位平台,应该考虑哪种类型的支持 烧焦 ?

    在过去,我遇到过一些模拟设备DSP 烧焦 是16位。我想,DSP有点像一个利基体系结构。(再说一遍,当时手工编码的汇编程序很容易胜过现有的C编译器所能做的,所以我在该平台上对C没有太多的经验。)

    12 回复  |  直到 11 年前
        1
  •  73
  •   Steve Jessop    12 年前

    char 也是德州仪器C54X DSP上的16位,例如在OMAP2中出现。还有其他16位和32位的DSP 烧焦 . 我想我甚至听说过24位数字信号处理器,但我不记得是什么,所以我可能是想象中的。

    另一个考虑因素是POSIX授权 CHAR_BIT == 8 . 所以如果你使用的是POSIX,你可以假设它。如果以后有人需要将您的代码移植到接近实现的POSIX上,那么您使用的函数正好是这样,但大小不同。 烧焦 那是他们的坏运气。

    不过,总的来说,我认为解决这个问题总是比思考更容易。只是类型 CHAR_BIT . 如果要精确的8位类型,请使用 int8_t .您的代码将很明显地无法在不提供代码的实现上编译,而不是以您不期望的大小静默地编译。至少,如果我遇到了一个我有充分理由假设的案例,那么我会断言它。

        2
  •  36
  •   John Feminella    15 年前

    在编写代码和考虑跨平台支持(例如,对于通用库)时,对于具有非8位char的平台,应该考虑哪些因素?

    与其说它是“值得考虑”的东西,不如说它是按规则玩的。例如,在C++中,标准称所有字节都具有“至少”8位。如果您的代码假定字节正好有8位,则说明您违反了标准。

    这可能现在看起来很愚蠢——” 当然 所有字节都有8位!”,我听到你说。但是很多非常聪明的人都依赖于那些没有保证的假设,然后一切都崩溃了。历史上充满了这样的例子。

    例如,大多数90年代早期的开发人员假设,采用固定周期数的特定无操作CPU定时延迟需要固定的时钟时间,因为大多数消费CPU的功率大致相同。不幸的是,计算机速度很快。这催生了带有“turbo”按钮的盒子的兴起,具有讽刺意味的是,它的目的是减慢计算机的运行速度,使使用延时技术的游戏能够以合理的速度进行。


    一位评论者问到,在标准中,char必须至少有8位。这是一段 5.2.4.2.1 . 本节定义 CHAR_BIT ,最小可寻址实体中的位数,默认值为8。它还说:

    其实施定义值应等于或大于所示数值(绝对值),符号相同。

    因此,任何等于8或更高的数字都适合由一个实现替换为 夏比特 .

        3
  •  31
  •   R Samuel Klatchko    15 年前

    具有36位体系结构的机器有9位字节。根据维基百科, machines with 36-bit architectures 包括:

    • 数字设备公司PDP-6/10
    • IBM 701/704/709/7090/7094
    • 大学1103/1103A/1105/1100/2200,
        4
  •  18
  •   Jerry Coffin    15 年前

    其中一些我知道:

    • dec pdp-10:变量,但通常是7位字符,每36位字打包5个,或者9位字符,每字4个
    • 控制数据主机(CDC-6400、6500、6600、7600、Cyber 170、Cyber 176等)6位字符,每60位字压缩10个。
    • Unisys主机:9位/字节
    • Windows CE:根本不支持'char'类型--需要16位wchar
        5
  •  14
  •   Ellioh    11 年前

    没有完全可移植的代码。-)

    是的,可能有各种字节/字符大小。是的,对于具有非常不寻常价值的平台,可能有C/C++实现。 CHAR_BIT UCHAR_MAX . 是的,有时可以编写不依赖于字符大小的代码。

    然而,几乎任何真正的代码都不是独立的。例如,您可能正在编写向网络发送二进制消息的代码(协议不重要)。您可以定义包含必要字段的结构。而不是必须序列化它。只将结构复制到输出缓冲区是不可移植的:一般来说,您既不知道平台的字节顺序,也不知道结构成员的对齐方式,因此结构只保存数据,但不描述数据序列化的方式。

    好啊。您可以执行字节顺序转换并移动结构成员(例如 uint32_t 或类似)使用 memcpy 进入缓冲区。为什么? 曼皮西 是吗?因为有很多平台在目标地址没有正确对齐时无法写入32位(16位,64位——没有区别)。

    所以,为了实现可移植性,您已经做了很多工作。

    现在是最后一个问题。我们有一个缓冲区。它的数据被发送到TCP/IP网络。这种网络假定8位字节。问题是:缓冲区应该是什么类型?如果你的字符是9位的?如果是16位?24?也许每个字符对应一个发送到网络的8位字节,并且只使用8位?或者可能将多个网络字节打包成24/16/9位字符?这是一个问题,很难相信只有一个答案适合所有情况。很多事情都依赖于目标平台的套接字实现。

    所以,我在说什么。通常,代码可以相对容易地生成 一定程度上可移植 . 如果您希望在不同的平台上使用代码,那么这样做非常重要。然而, 提高可移植性超出了这一标准,这需要付出很多努力,而且往往很少付出什么代价。 ,因为真正的代码几乎总是依赖于其他代码(上面例子中的套接字实现)。我敢肯定,对于90%的代码能力来说,在字节数不是8位的平台上工作几乎是无用的,因为它使用绑定到8位的环境。只需检查字节大小并执行编译时断言。几乎可以肯定的是,对于一个非常不寻常的平台,您必须重写很多东西。

    但是如果您的代码是高度“独立的”——为什么不呢?您可以以允许不同字节大小的方式编写它。

        6
  •  9
  •   dmckee --- ex-moderator kitten    15 年前

    看来你仍然可以 buy an IM6100 (即芯片上的PDP-8)出仓库。这是一个12位的体系结构。

        7
  •  9
  •   Alok Singhal    15 年前

    许多DSP芯片都有16位或32位 char . 钛通常会制造这样的芯片 for example .

        8
  •  5
  •   petantik    15 年前

    例如,C语言和C++编程语言将字节定义为“足以容纳执行环境的基本字符集的任何成员的数据的可寻址单元”(C标准的第3.6条)。由于C char整型数据类型必须至少包含8位(第5.2.4.2.1条),因此C中的一个字节至少能够容纳256个不同的值。C和C++的各种实现将字节定义为8, 9, 16位、32位或36位。

    引用自 http://en.wikipedia.org/wiki/Byte#History

    但对其他语言不太确定。

    http://en.wikipedia.org/wiki/IBM_7030_Stretch#Data_Formats

    将该计算机上的字节定义为可变长度

        9
  •  4
  •   PrgTrdr    14 年前

    DECPdp-8系列有一个12位字,尽管通常使用8位ASCII作为输出(主要在电传打字机上)。但是,还有一个6位字符代码,允许您在一个12位字中编码2个字符。

        10
  •  3
  •   bta    15 年前

    例如,Unicode字符长度超过8位。正如前面提到的,C规范根据数据类型的最小大小来定义数据类型。使用 sizeof 以及 limits.h 如果您想查询您的数据类型,并准确地发现它们对于您的配置和体系结构的大小。

    出于这个原因,我尝试使用如下数据类型 uint16_t 当我需要一个特定位长度的数据类型时。

    编辑: 对不起,我最初误解了你的问题。

    C规范规定 char 对象“足够大,可以存储执行字符集的任何成员”。 极限.h 列出了最小8位的大小,但该定义保留了 烧焦 打开。

    因此,A 烧焦 至少与体系结构执行集的最大字符一样长(通常向上取整到最接近的8位边界)。如果您的体系结构具有更长的操作码,则 烧焦 尺寸可能更长。

    历史上,x86平台的操作码只有一个字节长,所以 烧焦 最初是一个8位值。当前的x86平台支持超过一个字节的操作码,但是 烧焦 它的长度保持在8位,因为程序员(以及大量现有的x86代码)习惯于这样做。

    在考虑多平台支持时,请利用中定义的类型 stdint.h . 如果使用(例如)uint16,则可以确保该值是任何体系结构上的无符号16位值,无论该16位值是否与 烧焦 , short ,请 int 或者别的什么。大部分的工作已经由编写编译器/标准库的人完成。

    如果你需要知道 烧焦 因为您正在执行一些需要它的低级硬件操作,所以我通常使用足够大的数据类型来保存 烧焦 在所有支持的平台上(通常16位就足够了),并通过 convert_to_machine_char 当我需要确切的机器表示的时候。这样,特定于平台的代码仅限于接口函数,大多数时候我可以使用 uint16英寸 .

        11
  •  3
  •   dd ee    12 年前

    对于具有非8位char的平台,应该考虑哪些因素?

    幻数出现,例如移位时;

    其中大部分可以很简单地处理 使用char_位,例如uchar_max而不是8和255(或类似)。

    希望您的实现能够定义这些:)

    这些是“共同的”问题……

    另一个间接的问题是,你有:

    struct xyz {
       uchar baz;
       uchar blah;
       uchar buzz; 
    }
    

    这可能“仅”在一个平台上使用(最佳情况)24位, 但可能需要其他地方72位…

    如果每个UChar持有“位标志”,并且每个UChar只有2个“有效”位或标志, 您当前正在使用,为了“清晰”,您只将它们组织成3个UChar, 然后,它可能会相对“更浪费”,例如,在一个具有24位UChar的平台上……

    没有什么位域不能解决,但它们还有其他要注意的事情。 为了…

    在这种情况下,只有一个枚举可能是获得“最小”的方法 实际需要的大小整数…

    也许不是一个真正的例子,但是像这样的东西在移植/播放一些代码时“咬”了我……

    事实上,如果一个UChar的规模是“正常”预期的三倍, 100这样的结构可能会在某些平台上浪费大量内存….. 在“正常”情况下,这不是什么大事……

    所以事情仍然可能是“坏”的,或者在这种情况下,由于 假设一个UChar在一个平台上相对于可用的RAM来说“不是非常浪费”,而在另一个平台上……

    问题可能更突出,例如,对于INTS或其他类型, 例如,你有一些需要15位的结构,所以你把它放在一个int中, 但在其他平台上,int是48位或其他什么…..

    “通常”您可以将其分成2个UChar,但例如,使用24位UChar 你只需要一个……

    所以枚举可能是更好的“通用”解决方案…

    但这取决于您如何访问这些位:)

    所以,他们的大脑后面可能有“设计缺陷”…… 即使代码仍然可以正常工作/运行,无论 UChar或uint的大小…

    有这样的事情要小心,即使在那里 你的代码中没有“神奇数字”…

    希望这是有道理的:)

        12
  •  1
  •   Richard Pennington    15 年前

    ints过去是16位(pdp11等)。进入32位体系结构是很困难的。人们越来越好了:几乎没有人认为指针会再适合一段时间(你说的不对?)或文件偏移量或时间戳,或…

    8位字符已经有点过时了。我们已经需要32位来保存世界上所有的字符集。