字节真的是最小可寻址单位吗?

Is Byte Really The Minimum Addressable Unit?

C11 标准的第 3.6 节将 "byte" 定义为 "addressable unit of data storage ... to hold ... character"。

C++11 标准的第 1.7 节将 "byte" 定义为 "the fundamental storage unit in the C++ memory model ... to contain ... character"。

两种定义都没有说"byte"是最小可寻址单元。这是因为标准有意从特定机器中抽象出来吗?您能否提供一个真实的机器示例,其中 C/C++ 编译器决定具有 "byte" longer/shorter 而不是最小可寻址单元?

字节是严格符合C代码的最小寻址单元。 C 实现执行程序的机器是否支持寻址较小的单元与此无关; C 实现必须呈现一个视图,其中字节是严格符合 C 代码的最小可寻址单元。

C 实现可能支持寻址更小的单元作为扩展,例如简单地定义某些指针操作的结果,而 C 标准未定义这些操作。

真实机器及其编译器的一个示例是 8051 系列,其中最小可寻址单元小于一个字节。我习惯的一种编译器是Keil C51。

最小寻址单位是位。你可以定义一个这种类型的变量,你可以读写它。但是,定义变量的语法是非标准的。当然,C51 需要几个扩展来支持所有这些。顺便说一句,不允许指向位的指针。

例如:

unsigned char bdata bitsAdressable;
sbit bitAddressed = bitsAdressable^5;

void f(void) {
    bitAddressed = 1;
}

bit singleBit;

void g(bit value) {
    singleBit = value;
}

Both definitions does not say that "byte" is the minimum addressable unit.

那是因为他们不需要。字节类型(charunsigned charstd::byte 等)有足够的限制来强制执行此要求。

字节类型的大小是explicitly defined to be precisely 1:

sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1.

按字节类型对齐is the smallest alignment possible:

Furthermore, the narrow character types (6.9.1) shall have the weakest alignment requirement

当然,这不一定是 1 的对齐方式。除了...确实如此。

看,如果对齐高于 1,则意味着简单的字节数组将无法工作。数组索引基于指针算法,指针算法根据sizeof(T)确定下一个地址。但是如果 alignof(T) 大于 sizeof(T),那么任何 T 数组中的第二个元素都会错位。这是不允许的。

因此,即使标准没有明确说明字节类型的对齐方式为 1,但其他要求确保它必须是。

总的来说,这意味着每个指向对象的指针都具有至少与字节类型一样严格的对齐方式。因此,相对于按字节类型的对齐方式,没有对象指针可以未对齐。因此,所有有效的非 NULL 指针(指向活动对象或指向尾后指针的指针)必须至少对齐到足以指向 char.

同样,两个指针之间的差异是defined in C++,因为这些指针指向的元素的数组索引之间存在差异(C++中的指针算法要求两个指针指向同一个数组)。加法指针算法如前所述基于 sizeof 所指向的类型。

考虑到所有这些事实,即使实现的指针的地址可以寻址小于 char 的值,C++ 抽象模型在功能上不可能生成一个指针并仍然将该指针计数为有效(指向 object/function、数组的末尾之后,或者为 NULL)。您可以使用整数转换来创建这样的指针值。但是你会创建一个无效的指针值。

因此,虽然从技术上讲,机器上可以有更小的地址,但您永远无法在有效的、格式良好的 C++ 程序中实际使用它们。

显然,编译器扩展无所不能。但就符合规范的程序而言,根本不可能生成针对字节类型未对齐的有效指针。

我在 1990 年代初期对 TMS34010 及其后继 TMS34020 图形芯片进行了编程,它们具有平面地址 space 并且 可寻址即地址索引每一位。这对于内存非常宝贵的那个时代的计算机图形非常有用。

embedded C-compiler 并没有真正直接访问单个位,因为从(标准)C 语言的角度来看,字节仍然是前面 [=22] 中指出的最小单位=].

因此,如果你想 read/write C 中的位流,你需要 read/write(至少)一次一个字节和缓冲区(例如,在编写算术或霍夫曼时编码器)。

(谢谢大家评论回复,字字有帮助)

编程语言的内存模型和目标机器的内存模型是不同的。

是的,字节是编程语言内存模型上下文中的最小可寻址单位。

不,字节不是机器内存模型上下文中的最小可寻址单位。例如,有些机器的最小可寻址单元比编程语言的 "byte" 长或短:

  • 更长:HP Saturn - 4-bit unit vs 8-bit byte gcc(感谢 Nate)。
  • 更短:IBM 360 - 36 位单元与 6 位字节(感谢 Antti)
  • 更长:Intel 8051 - 1 位单位与 8 位字节(感谢 Busybee)
  • 更长:Ti TMS34010 - 1 位单位与 8 位字节(感谢 Wcochran)