【问题标题】:Why is the address of this volatile variable always at 1?为什么这个 volatile 变量的地址总是为 1?
【发布时间】:2012-01-04 13:44:04
【问题描述】:

我想检查我的变量的地址

volatile int clock;
cout << &clock;

但它总是说 x 在地址 1。我做错了什么吗??

【问题讨论】:

标签: c++ iostream implicit-conversion cout memory-address


【解决方案1】:

iostreams 会将大多数指针转换为 void * 以供显示 - 但 volatile 指针不存在转换。因此,C++ 回退到隐式转换为bool。如果要打印地址,请显式转换为void*

std::cout << (void*)&clock;

【讨论】:

  • 是的,有一个自动转换。只是它会自动转换为bool,而不是void *,因为C++ 没有针对指针自动转换为void *(C 有,但C++ 需要显式转换)
  • @bdonlan:你搞错了。任何普通指针都可以隐式转换为void*,它是void*T*,需要强制转换。
  • 这个答案是不正确的。 T*void* 的转换是隐式的。
  • @bdonlan 抱歉,C++ 确实有将T* 隐式转换为void*。所写的答案是错误的,或者至少是不完整的; C++ 不支持的是隐式抛弃volatile
  • @JamesKanze 大概是因为非volatile 指向volatile 对象的指针完全允许volatile 应该阻止的那种内存缓存?
【解决方案2】:

const void* 有一个operator&lt;&lt;,但volatile void* 没有operator&lt;&lt;,隐式转换不会删除volatile(它也不会删除const)。

正如 GMan 所说,指向的类型的 cv 限定应该与打印地址的业务无关。也许 27.7.3.6.2 中定义的重载应该是operator&lt;&lt;(const volatile void* val);,我看不出有什么缺点。但事实并非如此。

#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";
}

输出:

bool
1
pointer
0x22cd28
now it's a pointer

【讨论】:

  • 比我快一秒,求 :(。补充一下:在 bdonlan 提出的解决方案中,c 样式转换为 const_cast。出于打印的目的,它并不是真的担心。
【解决方案3】:

这是因为operator &lt;&lt; 没有重载,它接受指向volatile 的指针,并且没有指针转换可以满足它。

根据 C++ 标准,

对于任何类型T、指向T、指向const T 和指向volatile T 的指针都被视为不同的参数类型,对T 的引用、对const T 的引用和引用到volatile T

Operator &lt;&lt; has no overload for pointers to non-static member,指向 volatile 的指针或函数指针,因此尝试输出此类对象会调用到 bool 的隐式转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-12
    • 2014-10-21
    • 2016-03-31
    • 1970-01-01
    • 2020-06-26
    • 2011-06-19
    • 2019-04-27
    相关资源
    最近更新 更多