我正在阅读与char
和byte
相关的post,并且会出现以下字样:
int*
仍然可以作为单个硬件指针实现,因为C ++允许sizeof(char*) != sizeof(int*)
。
如何理解' C ++允许sizeof(char*) != sizeof(int*)
'?
答案 0 :(得分:3)
有(或曾经)的机器只能处理整个“单词”,其中一个单词足够大以容纳多个字符。例如,PDP-6/10的字长为36位。在这样的机器上,您可以实现9位字节并将字节指针表示为字中的字指针和位索引的组合。对于这样的指针,一个天真的实现需要两个单词,即使整数指针只是一个单词指针,占用一个单词。
(真正的PDP-6/10允许更小的字符大小 - 6位和7位编码是常见的,取决于用例 - 并且由于指针不能占据整个字,因此可以制作包含位偏移和字地址的字符指针适合单个单词。但是现在类似的架构不会对地址空间有严格的限制,因此不再适用。)
答案 1 :(得分:2)
简而言之,标准并不保证,结果是实现定义的。
来自sizeof
的标准($ 5.3.3 / 1 Sizeof [expr.sizeof])
sizeof运算符产生对象中的字节数 表示其操作数。
和指针是复合类型($ 3.9.2 / 1.3复合类型[basic.compound])
指向void或对象或函数的指针(包括静态成员) 给定类型的类,8.3.1;
和($ 3.9.2 / 3化合物类型[basic.compound])
指针类型的值表示为实现定义。
即使($ 3.9.2 / 3复合类型[basic.compound])
布局兼容类型的指针应具有相同的值 表示和对齐要求(3.11)。
但char
和int
不需要具有相同的值表示。标准只说($ 3.9.1 / 2基本类型[basic.fundamental])
有五种标准的有符号整数类型:“signed char”,“short” int“,”int“,”long int“和”long long int“。在此列表中,每种类型 提供至少与列表中前面的存储一样多的存储空间。
和($ 3.9.1 / 3基本类型[basic.fundamental])等。
每个有符号整数类型具有与其相同的对象表示 相应的无符号整数类型。
答案 2 :(得分:2)
itsnotmyrealname 和 rici 触及硬件驱动程序,但我认为这可能有助于完成导致不同指针大小的最简单方案... < / p>
想象一下,CPU可以处理32位字的内存,而C ++ int
类型也是32位宽。
这个假设的CPU使用编号对特定字进行寻址:第一个字为0(字节0-3),第二个为1(字节4-7),依此类推。因此,int*{0}
是你记忆中的第一个词(假设没有奇怪的nullptr
恶作剧要求),int*{1}
第二个等等。
编译器应该怎样做才能支持8位char
类型?它可能必须使用char*
来实现int*
支持以识别内存中的字,但仍需要额外的两位来存储0,1,2或3来说明该字中的哪个字节被指出。它实际上需要像C ++程序一样生成机器代码,如果使用...
struct __char_ptr
{
unsigned* p_;
unsigned byte_ : 2;
char get() const { return (*p_ & (0xFF << (8*byte_)) >> 8*byte_; }
void set(char c) { *p_ &= ~(0xFF << (8*byte_)); *p |= c << 8*byte_; }
};
在这样的系统上 - sizeof(__char_ptr) > sizeof(int*)
。 C ++标准的灵活性允许具有此类或类似问题的奇怪系统的兼容C ++实现(以及代码可移植性)。
答案 3 :(得分:2)
这也是为什么we can not forward declare enums without providing the underlying size在我的回答中我提供了几个参考资料来解释为什么会这样的原因。
在此comp.lang.c++ discussion: GCC and forward declaration of enum中:
[...]虽然在大多数架构上,但在一些架构上可能不是问题 架构指针将具有不同的大小,以防它是一个 char指针。 [...]
我们可以从这个C-Faq条目Seriously, have any actual machines really used nonzero null pointers, or different representations for pointers to different types? 中找到它:
较旧的,字寻址的Prime机器也因为需要比字指针(int *)更大的字节指针(char *)而臭名昭着。 [...]某些64位Cray机器在一个字的低48位中表示int *; char *另外使用高16位中的一些来指示字内的字节地址。 [...]
此外:
[...] Data General的Eclipse MV系列有三种架构支持的指针格式(字,字节和位指针),其中两个由C编译器使用:字符指针用于char *和void *,以及其他一切的词指针。由于历史原因在从16位Nova线演变32位MV线期间,字指针和字节指针在字中的不同位置具有偏移,间接和环保护位。将不匹配的指针格式传递给函数会导致保护错误。最终,MV C编译器添加了许多兼容性选项,以尝试处理具有指针类型不匹配错误的代码。 [...]旧的HP 3000系列使用不同的字节地址寻址方案而不是字地址;就像它上面的几台机器一样,它使用char *和void *指针的不同表示而不是其他指针。 [...]
答案 4 :(得分:1)
标准说:
5.3.3尺寸
sizeof(char),sizeof(signed char)和sizeof(unsigned char)是1。 sizeof应用于任何其他基本类型的结果( 3.9.1)是实现定义的。
由于指针是“复合类型”,并且标准没有提到指针之间的字节大小一致性,编译器编写者可以随心所欲地做。