Here's an excerpt from Section 6.7.1 (footnote 101) of the C99 standard (pdf):
The implementation may treat any
registerdeclaration simply as anautodeclaration. However,whether or not addressable storage is actually used, the address of any part of an object declared with storage-class specifier register cannot be computed, either explicitly (by use of the unary&operator as discussed in 6.5.3.2) or implicitly (by converting an array name to a pointer as discussed in 6.3.2.1). Thus, the only operator that can be applied to an array declared with storage-class specifierregisterissizeof.
And from Section 7.1.1, Paragraph 3 of the C++ standard (pdf):
A
registerspecifier has the same semantics as anautospecifier 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]
So, this seems like another case of C and C++ having "identical" features that behave the way you'd expect them most of the time, but diverge and cause confusion other times. In this situation, I think the way C does it makes sense since it
- is semantically closest to being correct and;
- doesn't do things behind your back.
Fun tidbits about register
The C++ group (WG21) wants to deprecate register:
The
registerkeyword serves very little function, offering no more than a hint that a note says is typically ignored. It should be deprecated in this version of the standard, freeing the reserved name up for use in a future standard, much likeautohas been re-used this time around for being similarly useless.Notes from the March, 2009 meeting:
The consensus of the CWG was in favor of deprecating
register.
Look what the C99 group (WG14) said about register (pdf) at a meeting:
General agreement to deprecate the “
auto” keyword. Should we ask WG21 to go back to the previous use of “register” (no address)? No, this will not fly with WG21.
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
using namespace std;
int main()
{
int i = 123;
auto int j = 456;
register int k = 789;
cout<<"Address of i = " << &i <<", Value = " << i << endl;
cout<<"Address of j = " << &j <<", Value = " << j << endl;
cout<<"Address of k = " << &k <<", Value = " << k << endl;
return 0;
}
Note that the address of i, j and k are very close implying that the compiler chose to ignore the 'register' keyword.

