I wanted to inspect the address of my variable
volatile int clock;
cout << &clock;
But it always says that x is at address 1. Am
iostreams will cast most pointers to void *
for display - but no conversion exists for volatile
pointers. As such C++ falls back to the implicit cast to bool
. Cast to void*
explicitly if you want to print the address:
std::cout << (void*)&clock;
This is because there is no overload for operator <<
that takes a pointer to volatile
, and there is no pointer conversion that could satisfy it.
According to C++ standard,
for any type
T
, pointer toT
, pointer toconst T
, and pointer tovolatile T
are considered distinct parameter types, as are reference toT
, reference toconst T
, and reference tovolatile T
.
Operator << has no overload for pointers to non-static member, pointers to volatile, or function pointers, so attempting to output such objects invokes implicit conversion to bool
.
There's an operator<<
for const void*
, but there's no operator<<
for volatile void*
, and the implicit conversion will not remove volatile
(it won't remove const
either).
As GMan says, the cv-qualification of the type pointed to should be irrelevant to the business of printing an address. Perhaps the overload defined in 27.7.3.6.2 should be operator<<(const volatile void* val);
, I can't immediately see any disadvantage. But it isn't.
#include <iostream>
void foo(const void *a) {
std::cout << "pointer\n";
}
void foo(bool a) {
std::cout << "bool\n";
}
int main() {
volatile int x;
foo(&x);
std::cout << &x << "\n";
int y;
foo(&y);
std::cout << &y << "\n";
void foo(volatile void*);
foo(&x);
}
void foo(volatile void *a) {
std::cout << "now it's a pointer\n";
}
Output:
bool
1
pointer
0x22cd28
now it's a pointer