using references to SFRs in gcc inline assembler
You could use pointers instead of references. With pointers, you have
the separate notions of “constant pointer” and “pointer to constant”. A
reference is a kind of pointer coated with syntactic sugar. However,
whereas you can have a “constant reference” (equivalent to pointer to
constant), I do not know how to declare a “reference with constant
address” (which would be the equivalent of a constant pointer). And
this is your issue: the "i" constraint in the asm statement requires
a constant.

Here is my take with pointers:

typedef volatile uint8_t * tRegister;

constexpr tRegister timer_register(tRegister a, tRegister b)
{ return MY_TIMER==0 ? a : b; }

// The `const' below is essential.
const tRegister OCRA = timer_register(&amp;OCR0A, &amp;OCR2A);

asm volatile("lds r24, %0" : : "i"(OCRA));


Of course, you then have to change all your OCRA = ...; statements
with *OCRA = ...;, which is awkward. But note that the avr-libc
defines the SFRs with macros equivalent to

#define OCR0A (*address_of_OCR0A)


If you want this convenience, you may have to resort to using similar
macros yourself.