C ++中易失性数据成员的地址
Posted
技术标签:
【中文标题】C ++中易失性数据成员的地址【英文标题】:Address of volatile data member in C++ 【发布时间】:2016-03-24 23:43:19 【问题描述】:int main()
volatile int a=26;
volatile int *p=&a;
cout<<p;
return 0;
在 Borland 编译器中输出为 26,在 gcc O/P 中为 1。为什么?
如果许多变量或大对象被声明为寄存器,编译器会自动禁止它加载到寄存器上,而是将它们加载到内存中,或者挂起、显示错误等,会发生什么?
谢谢:)
【问题讨论】:
您认为volatile
的意思是“注册”吗?
Borland 编译器陈旧且损坏。在 gcc 中,由于这个原因,它显示为 bool:***.com/questions/2501737/…
volatile 表示编译器不会通过将变量存储在寄存器上来优化代码。声明 volatile 意味着确保变量将存储在内存中,我知道,在内存中我们没有像 1 或 26 这样的地址
在这种情况下,我无法理解您的问题“如果将许多变量或大对象声明为寄存器...会怎样?”
volatile int *p=&a;
使p
成为指向a
的指针,将a
的地址存储在内存中。这与a
的内存内容无关,即26
。如果您将其转换为(void*)p
,您将看到内存地址。如果没有演员表,GCC 会使用奇怪的 operator<<(std::ostream&, T)
重载;可能T
是bool
,正如其他人声称的那样,输出实际上毫无意义:它只是意味着指针不是nullptr
。正如 interjay 所说,Borland 输出 26
完全崩溃和莫名其妙。
【参考方案1】:
std::ostream
中的operator<<(volatile int*)
没有重载,因此考虑了隐式类型转换。 volatile
指针不能隐式转换为非volatile
,因此 std::ostream::operator<<(void*)
- 通常用于指针的情况 - 不是一个选项。但是,即使是 volatile 指针也可以转换为类型的重载:operator<<(bool)
。由于指针不为空,它的转换值为true
,cout
输出为1
。如果要打印地址,则将const_cast
去掉volatile
限定符,以便使用到void*
的隐式转换。如果要打印指向的值,则通过取消引用传递指向的值而不是指针。
Borland 似乎提供了一个取消引用指针的非标准重载。
在 C++ 中无法将变量声明为寄存器。是的,有一个register
关键字,但是它并没有改变程序的含义,并且已经被弃用(并且计划在c++17版本的标准中被移除)。完全由编译器决定变量是存储在内存中还是仅存储在寄存器中。
【讨论】:
以上是关于C ++中易失性数据成员的地址的主要内容,如果未能解决你的问题,请参考以下文章