Reputation: 744
I'm working through the C++ Primer and if I understand it correctly:
// A plain int.
int i {0};
// Top-level const ints.
const int ci {42};
const int ci2 {0};
// A low-level pointer to const int.
const int * pci {&ci};
// Low-level, because the referenced object can't be changed.
*pci = 0; // error
// But not top-level, because it can be changed to point to another object.
pci = &ci2; // fine
// This is both top-level and low-level const
// because both the pointer and the object it
// points to are const:
const int * const cpci {&ci};
*cpci = 0; // error
cpci = &ci2; // error
Now the question. Is there a naming convention for a constness which is neither top-level nor low-level? I.e. the pointer itself is not const but it points in a constant way to a non-const object? Or is this a special case of low-level constness? Example:
int i {0];
int j {42};
// The following pointer is not const itself.
// The object it's pointing to is not const but
// it can't be manipulated through the pointer.
const int * pci {&i};
*pci = 42; // error
// All these are fine:
++i;
pci = &j;
++j;
*pci = 42; // error as above
Edit after accepting Lightness Races in Orbit's answer:
My IDE calls them read-only pointers which makes sense to me
although the referenced object can be changed with this ugly cast:
*const_cast<int*>(pci) = 21;
Upvotes: 4
Views: 1136
Reputation: 385144
No, not really.
The distinction you're making is between an object with const
-qualified type, and an expression with const
-qualified type.
Since (from a usage perspective) it very rarely matters which one is in play†, there is no meaningful terminology to distinguish them in any given case.
This does admittedly make it a little cumbersome to explain why the following program is totally valid and well-defined (if really, really bad style), despite casting away the const
:
void foo(const int& x)
{
// the expression `x` has type `const int&` (before decay),
// but after casting away the constness we can modify the
// referent, because it happens to actually be non-`const`.
const_cast<int&>(x) = 66;
}
int main()
{
int x = 42; // object is not const!
foo(x);
}
For what it's worth, although "top-level const" is standard terminology, I'm not so sure about your "low-level const". The terms aren't even properly symmetrical! Pfft.
† In foo()
above we wouldn't actually write the const_cast
because we would assume that all inputs are references to objects that really are const
.
Upvotes: 3