sizeof(T *)!= sizeof(const T *)?

我正在和老板讨论这个问题。 他们说“是的,他们可以是不同的。”

对于sizeof(T*) != sizeof(const T*)是否有可能sizeof(T*) != sizeof(const T*)

不,他们不能不同 对于充分不同的T1T2sizeof(T1 *)可以与sizeof(T2 *) ,但是如果T2只是const T1 ,则:

3.9.2化合物types[basic.compound]

3指向版式兼容types的cv-qualified和cv-unqualified版本(3.9.3)的指针应具有相同的值表示和alignment要求(3.11)。 […]

而任何types的T都是与自身布局兼容的:

3.9types[basic.types]

11如果两种typesT1T2是相同的types,则T1T2布局兼容types。 […]


值表示与对象表示有关,不能具有相同的值表示,而不具有相同的对象表示。 后者意味着需要相同数量的位。

3.9types[basic.types]

4 Ttypes对象的对象表示formsTtypes对象占用的N个 unsigned char对象的序列,其中N等于sizeof(T) 。 对象的值表示是保存typesT的值的位集合。 对于可复制types,值表示是对象表示中的一组位,用于确定一个 ,该是实现定义的一组值中的一个离散元素。 44

44)的目的是C ++的内存模型与ISO / IEC 9899编程语言C的内存模型兼容。

这个要求的要点是,它不只是说这两种types具有相同的对象表示,是因为T *const T *不仅具有相同的位数,而且在T *也是相同的位T *const T *组成的值。 这是为了不仅保证sizeof(T *) == sizeof(const T *) ,而且还意味着你可以使用memcpyT *指针值复制到const T *指针值,反之亦然一个有意义的结果,你会得到与const_cast完全相同的结果。

对准要求也提供了一些额外的保证,但是解释得很好,与这个问题没有直接关系,这个标准有些问题会破坏一些预期的保证,所以我觉得这里最好不要理会。

Microchip发布了这样的C编译器,其中sizeof(T*)为2,但sizeof(const T*)为3。

C编译器在几个方面不符合标准,所以这没有提到这是有效的(我怀疑这不是和其他答案一致)。

嗯,这是非常神秘的,但我认为理论上可能有一个架构,例如,在地址0有256个字节的RAM,比如说,在更高的地址有一些千字节的ROM。 而且可能有一个编译器会为int *i创build一个8位指针,因为8位足以容纳高度有限的RAM区域中的任何对象的地址,并且当然隐含地知道任何可变对象在RAM中区。 const int *itypes的指针将需要16位,以便它们可以指向地址空间中的任何位置。 8位指针int *i可以强制转换为16位指针const int *i (反之亦然),所以C标准的可铸造性要求将得到满足。

但是如果现在有这样一个架构,我一定会喜欢看(但不要为它写代码):)

就标准C ++而言,它们不能不同。 C和C ++在这一点上是相似的。

但是那里有许多架构,为它们编写的编译器不遵循这个规则。 的确,那么我们实际上并没有谈论标准的C ++,有些人会认为这个语言不是C ++,但是我的阅读(在添加语言律师标签之前)更多的是可能性。

在这种情况下,这是可能的。 您可能会发现指向ROM(因此是const)的指针与指向RAM的指针(const或non const)的大小不同。

如果你确信你的代码只能在标准的抱怨编译器上结束,那么你的假设是正确的。 如果没有,那么我会仔细考虑依靠他们的大小是相同的。