In C, we cannot use & to find out the address of a register variable but in C++ we can do the same. Why is it legal in C++ but not in C? Can someone please explain this
The register keyword is a hint only and can be ignored. Most C++ compilers ignore it all of the time, but any C++ compiler will ignore it if you take the address of the variable, or create a reference to it.
On the other hand, a C++ compiler doesn't have to ignore "register" just because you take the variable's address. In theory the compiler could store it in a register and give you some magic pointer value that is somehow mapped to the register behind the scenes, but that would be a lot of work for very little gain, so no compiler (that I know of) does anything like that.
Since register is ignorable in C as well, I suspect that the explicit proscription against taking addresses of register variables was simply to alleviate C compilers from the burden of checking for this.
The relevant part of the C++ standard is 7.1.1.3:
A register specifier has the same semantics as an auto specifier together with a hint to the implementation that the object so declared will be heavily used. [Note: the hint can be ignored and in most implementations it will be ignored if the address of the object is taken. —end note]