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=&amp;a; 使p 成为指向a 的指针,将a 的地址存储在内存中。这与a的内存内容无关,即26。如果您将其转换为(void*)p,您将看到内存地址。如果没有演员表,GCC 会使用奇怪的 operator&lt;&lt;(std::ostream&amp;, T) 重载;可能Tbool,正如其他人声称的那样,输出实际上毫无意义:它只是意味着指针不是nullptr。正如 interjay 所说,Borland 输出 26 完全崩溃和莫名其妙。 【参考方案1】:

    std::ostream 中的operator&lt;&lt;(volatile int*) 没有重载,因此考虑了隐式类型转换。 volatile 指针不能隐式转换为非volatile,因此 std::ostream::operator&lt;&lt;(void*) - 通常用于指针的情况 - 不是一个选项。但是,即使是 volatile 指针也可以转换为类型的重载:operator&lt;&lt;(bool)。由于指针不为空,它的转换值为truecout 输出为1。如果要打印地址,则将const_cast 去掉volatile 限定符,以便使用到void* 的隐式转换。如果要打印指向的值,则通过取消引用传递指向的值而不是指针。

    Borland 似乎提供了一个取消引用指针的非标准重载。

    在 C++ 中无法将变量声明为寄存器。是的,有一个register关键字,但是它并没有改变程序的含义,并且已经被弃用(并且计划在c++17版本的标准中被移除)。完全由编译器决定变量是存储在内存中还是仅存储在寄存器中。

【讨论】:

以上是关于C ++中易失性数据成员的地址的主要内容,如果未能解决你的问题,请参考以下文章

STM32-常用存储器

superthis

数据可视化项目测试中易被忽略的缺陷

SQL Server中易混淆的数据类型

Teradata 中易失性表的光标

必看 :大数据挖掘中易犯的11大错误