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.