This code is well-defined and there is no problem.
The code const int &b
means that:
b
refers to an int
- The expression
b
may not be used to modify that int
.
However it is perfectly fine for the int
to be modified by other means. For example, via a
here. When compiling f
, the compiler must take into account that a
and b
might both refer to the same object.
Some compilers have extensions to specify that function parameters (or other variables) should not alias; e.g. in MSVC++ 2015 you can write:
void f(int & __restrict a, const int & __restrict b)
and then the compiler may compile f
assuming that &a != &b
, i.e. it might output 6 5
for your code, which would now be silent undefined behaviour -- the compiler isn't required to diagnose violations of __restrict
When writing a function that takes multiple reference or pointer parameters of the same type (excluding qualifications), or char
, you must be aware that it's possible some parameters will alias the other parameters. You could hand this by one of the following:
- Write your code so that it works even if the parameters alias
- Include a check like
if ( &a == &b ) return;
- Use
__restrict
and document that the onus is on the caller to not alias.
A common case this shows up is the overloaded operator=
for a class. This function needs to support someone writing x = x;
, i.e. *this
may alias the function parameter. Sometimes people solve this by checking if ( &a == this ) return;
, and sometimes they omit that check but design the implementation so that it still works even if those were equal.