Followers 0

# What are constant references used for?

## 20 posts in this topic

In C++, is there an actual usage for constant references, or is it there for completeness(and perhaps to add ambiguity.)?

I would simply use constant variable or a preprocessor substitution to a literal value. Edited by gasto
0

##### Share on other sites

A const reference can reference both const and non-const objects, but you can't take a non-const reference to a const object, so there's no backdoor to modifying a const object. At least not without further subversion of the type system.

It would be difficult to imagine modifying a literal like 1 or the address of the first character of "Hello". In C that is undefined behaviour if allowed(if I recall correctly).
0

##### Share on other sites

Read-only visibility into an object is also a common use case, i.e. returning a const reference from a function.

Would it refer to anything? I mean, after the execution of the function, local variables with automatic block duration would be wiped out of memory, hence the reference returned by such hypothetical function would refer to garbage.
0

##### Share on other sites

but this probably only ever happens if the compiler knows for certain that you never use the reference in a way that would depend on the parameter being in memory.

How wouldn't it? I mean, 5 is always going to be 5 and it is known at compile time.
-1

##### Share on other sites

A const reference can reference both const and non-const objects, but you can't take a non-const reference to a const object, so there's no backdoor to modifying a const object. At least not without further subversion of the type system.

It would be difficult to imagine modifying a literal like 1 or the address of the first character of "Hello". In C that is undefined behaviour if allowed(if I recall correctly).

You can't without subverting the type system -- and that's the point. But when you alias an object by using a different name -- say, with a pointer or reference -- the constness of that new name is carried from the new name, not the object. That's why the compiler enforces it this way -- the new name can be more restrictive (a const reference or const pointer can alias either a const or non-const object), but never less restrictive (which is why a non-const reference or non-const pointer can't alias a const object). You can always further subvert the type system until you have a non-const alias to a const object, and when you do the compiler will happily accept it and your program will not-so-happily crash when you attempt to modify it (typically. I don't know whether its undefined or unspecified, specifically, but its not legal code).

Diving a little deeper on a related issue, its something of a misnomer in C or C++ to say that you have a "const int" -- the platform might (or might not) actually protect the memory that stores that int with some mechanism, or it might place it in the .TEXT segment rather than .DATA, but the languages don't require that. It would be more accurate to think of it as having an "int-sized memory location whose name carries and enforces the qualities of a const value". The compiler will do its best to keep constness transitory when you alias the original name or address with a new name, but this is C and C++ where the programmer is god -- there are always ways around.

0

##### Share on other sites

const TYPE & VAR
#3: To indicate the difference between access on read and access on write. In the following example, we have an orientation class with a position (type CVector3). In order to avoid updating the matrix every time it is read, we want to set a dirty flag only when it is written.

enum {
ORIENTATION_POS_DIRTY = (1 << 0),
ORIENTATION_SCALE_DIRTY = (1 << 1),
ORIENTATION_ROT_DIRTY = (1 << 2),
ORIENTATION_NORMALIZE = (1 << 3),
};
const CVector & COrientation::Pos() const {
// No dirty flags; just return the value for read-only.
return m_vPos;
}
// Write version.
CVector & COrientation::Pos() {
m_ui32Dirty |= ORIENTATION_POS_DIRTY;  // Setting this bit indicates that later we need to re-update our matrix.
return m_vPos;
}
m_aChar.Pos() += m_aPlatform.Pos();  // Only character’s position vector was accessed for write; it will cause a matrix rebuild for the character, not for the platform.

How will the compiler discern between one overloaded function and the other? Both have the same signature.
0

##### Share on other sites

[Edit:] Ah, perhaps you are meaning Type & const, instead of const Type & ? Yeah, that's pointless (and I think invalid code). But const Type & is definitely valuable.

That is true. However, sneak-peeking on other's people interpretation is useful.
0

##### Share on other sites

How will the compiler discern between one overloaded function and the other? Both have the same signature.

const CVector & COrientation::Pos() const {
CVector & COrientation::Pos() {
The difference in the signature is the const at the end of the line. As Brother Bob mentioned, if the variable is declared const, the version with the const at the end will be called.
0

##### Share on other sites
Waste of a post and my time.
See below for why.

L. Spiro Edited by L. Spiro
0

##### Share on other sites

How will the compiler discern between one overloaded function and the other? Both have the same signature.

In addition to the explanation given by Brother Bob and reiterated by Rattrap, I showed a different example:
m_aChar.Pos() += m_aPlatform.Pos();
Neither m_aChar nor m_aPlatform are const objects in this context (neither were originally declared with const).

Instead, one is being accessed for read and the other for write.
When possible, the compiler will always choose the const method if it exists.

If only the const method existed, the line would be invalid because you couldn’t write to m_aChar.
If only the non-const method existed, both m_aChar.Pos() and m_aPlatform.Pos() would go through the non-const version (which would set a dirty flag on m_aPlatform and needlessly cause an update to its matrix).

Since both exist, the compiler will try to use const for both m_aChar and m_aPlatform, but it will realize that m_aChar is being accessed for write, so it instead must use the non-const version. m_aPlatform is accessed for read so the default (the const version) remains as the compiler’s choice.

L. Spiro

It doesn't matter whether you write to the returned value or just read from it; the function that is called (the const or non-const vatiant) is determined exclusively based on the object it is called on. The non-const is called when possible, and the const is called when necessary.

My head is spinning. Is this a C++ standard feature? From what I recall, a function's signature only includes its name and parameters. Is a reference return type considered a parameter? Edited by gasto
0

## Create an account

Register a new account