According to the odr-use defintion, an object is odr-used if a reference is bound to it. This is why f makes S::x odr-used I believe. What I can not understand is how is that any different from the comma operator which also binds its arguments to reference parameters
struct S {
static const int x = 0; // static data member
// a definition outside of class is required if it is odr-used
};
const int& f(const int& r);
int n = b ? (1, S::x) // S::x is not odr-used here
: f(S::x); // S::x is odr-used here: a definition is required
Those are just examples for how an overloaded comma operator might be defined in a class. It's the usage of such an overload that would necessarily trigger odr-use, when you bind to the arguments.
That usage hasn't been written into your program, nor has an operator overload at all for that matter.
You're just using the built-in comma operator.
(A more interesting question might be whether the right-most operand to this operator is still odr-used, because from the wording it looks to me like it is! Do remember that an odr-use violation isn't required to generate a build error, and in certain situations it won't.).
I would argue that the cppreference page is possibly a little unclear in that regard.