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

3

25

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 i doing something wrong??

Yulma answered 23/11, 2011 at 8:44 Comment(2)
1 need not always represent numerical value -- could be logical as well.Anaphrodisiac
Possible duplicate of Why does std::cout convert volatile pointers to bool?Rockyrococo
M
22

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;
Matelote answered 23/11, 2011 at 8:46 Comment(6)
Yes, there is an automatic conversion. It's just that it's automatically converted to bool, not void *, as C++ does not have automatic conversion to void * for pointers (C does, but C++ requires an explicit cast)Matelote
@bdonlan: You've got it backwards. Any normal pointer can be implicitly converted to void*, it's void* to T* that requires a cast.Incisor
This answer is incorrect as it stands. The conversion of T* to void* is implicit.Breeding
@Matelote Sorry, but C++ does have an implicit conversion of T* to void*. The answer as written is wrong, or at least incomplete; what C++ doesn't support is implicitly casting away volatile.Breeding
@JamesKanze Presumably that's because non-volatile pointers to volatile objects permit exactly the kind of memory-caching that volatile is supposed to prevent?Spectacled
In C++ C-style casting should be avoided - this should be changed to const_cast.Codon
S
17

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
Sharpnosed answered 23/11, 2011 at 9:47 Comment(1)
Beat me by literally one second, urg :(. To add on: in the solution proposed by bdonlan, the c-style cast as a const_cast. For the purpose of printing, it's not really a concern.Incisor
Q
0

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.

Qr answered 29/9, 2016 at 14:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.