Why is the address of this volatile variable always at 1?

可紊 提交于 2019-11-28 23:09:32

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;

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

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 to T, pointer to const T, and pointer to volatile T are considered distinct parameter types, as are reference to T, reference to const T, and reference to volatile 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!