Could it be the case that sizeof(T*) != sizeof(const T*)?
I'm arguing with my boss about this. They say "Yes they can be different."
Is it possible that sizeof(T*) != sizeof(const T*)
for a type T
?
No, they can't be different. For sufficiently different T1
and T2
, sizeof(T1 *)
can be different from sizeof(T2 *)
, but if T2
is just const T1
, then:
3.9.2 Compound types [basic.compound]
3 [...] Pointers to cv-qualified and cv-unqualified versions (3.9.3) of layout-compatible types shall have the same value representation and alignment requirements (3.11). [...]
And any type T
is layout-compatible with itself:
3.9 Types [basic.types]
11 If two types
T1
andT2
are the same type, thenT1
andT2
are layout-compatible types. [...]
Value representation is in relation to the object representation, you can't have the same value representation without also having the same object representation. The latter means the same number of bits is required.
3.9 Types [basic.types]
4 The object representation of an object of type
T
is the sequence of Nunsigned char
objects taken up by the object of typeT
, where N equalssizeof(T)
. The value representation of an object is the set of bits that hold the value of typeT
. For trivially copyable types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation-defined set of values.4444) The intent is that the memory model of C++ is compatible with that of ISO/IEC 9899 Programming Language C.
The point of the requirement, the reason it doesn't just say that the two types have the same object representation, is that T *
and const T *
not only have the same number of bits, but also that it's the same bits in T *
and const T *
that make up the value. This is meant to guarantee not only that sizeof(T *) == sizeof(const T *)
, but it means even that you can use memcpy
to copy a T *
pointer value to a const T *
pointer value or vice versa and get a meaningful result, the exact same result you would get with const_cast
.
The alignment requirements provide some additional guarantees too, but they're complicated to explain properly and not directly relevant to this question, and there are issues in the standard that undermine some of the intended guarantees, so I think that's best left ignored here.
Microchip released such a C compiler where the sizeof(T*)
was 2 but sizeof(const T*)
was 3.
The C compiler was not standards-compliant in a few ways, so this says nothing about this being valid (I suspect it isn't and other answers agree).
Hmm, this is highly esoterical, but I'm thinking that theoretically there could be an architecture which has, say, 256 bytes of RAM in address 0 and, say, some kilobytes of ROM in higher addresses. And there could be a compiler that would create a 8-bit pointer for int *i
because 8 bits is enough to hold the address of any object in the highly limited RAM area and any mutable object of course is implicitly known to be in the RAM area. Pointers of type const int *i
would need 16 bits so that they could point to any location in the address space. The 8-bit pointer int *i
is castable to a 16-bit pointer const int *i
(but not vice versa) so the castability requirement of C standard would be satisfied.
But if there's such an architecture in existense, I'd sure like to see it (but not write code for it) :)