Does the C++ standard allow it?
Sure, why not. There is no way you could tell the difference. The so-called "as-if rule" allows compilers to do any optimization as long the observable behavior is the same as if it didn't do any optimizations (side note: there are exceptions, where optimizations are allowed to change observable behavior).
Conceptually, animal and dog are two variables, each of pointer size, ...
Nope. Conceptually, references are aliases. They need not take any space, because they are just a different name for the actual object. The C++ standard does not specify the size a reference takes or how it is implemented. sizeof
a reference gives you the size of the refered to object. The address of a reference is the address of the referd to object. I am not aware of any way to tell the difference if a reference is implemented as pointer or in any other way (and I strongly doubt that there is a portable way).
Would modern compilers do it?
To answer this I suggest you to take some real code and look at the compilers output. This is a nice tool to help with that: https://godbolt.org/.
PS: I sense a small misunderstanding. In fact the const
in your example is not that relevant. Having a const
reference does not imply that the value will not change. It only means that you are not allowed to change the value through that reference. Maybe best exaplained by a small example:
struct foo {
const int& ref;
};
int main() {
int x = 1;
foo f{x};
x = 42;
}
Here f
holds a const
reference to x
. That doesn't mean that x
will never get modified. It only means that f
cannot modify x
via ref
. This is especially important in a multithreaded environment, where assuming that an object is const
just because you have a const
reference will cause trouble.