Let's first agree that ALL UPPERCASE is an eyesore and should be minimized.
In C and C++ it's therefore used as a convention for macros, and macros only, because macros are equally ugly, not to say evil.
Early C didn't have const, so constants had to be expressed as macros. Also, in those early days programs were much shorter, so that the practices that are ungood today could be used (e.g. IIRC Brian Kernighan wrote code with lots of non-uppercase macros). And also, in those days keyboards that didn't have lowercase letters did exist; I used one such, on the Norwegian Tandberg EC-10 computer, about 1980 or 1979 I think it was.
So, Java picked up the uppercase convention for constants from early C. Meanwhile, and perhaps even before that (I'm not sure of the chronology here), C got constants. However, while of course some/many C programmers were stuck in the earlier convention-by-necessity of constants as uppercase macros, C++ programmers were more sensible.
The big problem nowadays is when people are taught Java first, or C (with conventions from the middle ages) first, and then come to C++, taking that foul uppercase convention with them.
int const answer = 42; // Nice, good, OK.
const int ANSWER = 0x2A; // Ouch!
#define COMPANYNAME_ANSWER 052 // Oh kill me, please.
Well you might have thought I mentioned uppercase-only keyboards in jest. Oh no. Because that's merely the oldest, most archaic technology limitation that has driven naming conventions, or at least affected how wrong/right they have seemed. Next, there was the problem of 7-bit serial transmission, which caused corresponding problems with the character codes (newspeak character encodings) used, which meant you had to restrict yourself to the letters of the English alphabet, A through Z.
Actually I recommend still doing that. That's where we're at! We haven't got further.
At the moment, as of 2011, standard C++ supports general Unicode in names (and has done so since 1998), while actual C++ implementations do not. In particular the g++ compiler is national character challenged. It stems from that dark ages technological limitation.
double blueberryJamViscosity = 0.0; // OK
double blåbærsyltetøyViskositet = 0.0; // Ouch!
Finally, on the subject of underscores versus interspersed uppercase letters,
- Reserve an easily recognized form for type names.
- Reserve ALL UPPERCASE for macros.
- Be consistent.
I think that's that, really, except for rules like "generally avoid single-letter name except for (loop, template param, blah blah)", and "avoid using l, easily confused with 1" and "avoid uppercase O, easily confused with 0". Also, of course, avoid using reserved names like starting with underscore followed by uppercase, containing two successive underscores, or starting with underscore and being in the global namespace.
Cheers & hth