我知道volatile
变量背后的概念。基本上所有对该变量的读写都必须。有没有办法允许优化器只使用所有的写操作,并假设读取将始终保持不变(除非通过写入修改)。
另外(沿着相同的行)有一种方法可以为编译器定义一种新类型的内存来存储变量。例如,如果我有一个带有SD卡的微控制器,我可以将SD卡定义为存储内存的地方(或者我必须自己完成所有的读/写操作)。
对于记录,我使用gcc作为我的编译器,如果有什么我可以在gcc上专门做(并且只有)
答案 0 :(得分:4)
我知道volatile变量背后的概念。
确定...
基本上必须对该变量进行所有读写操作。
绝对不是“基本上”。
是否有办法允许优化器只使用所有写操作并假设读取始终保持不变(除非通过写入修改)。
没有
< - snip - >
volatile用于建模对内存映射I / O的读/写访问。 “写入”此类I / O通常会触发电子设备中的活动,即使写入的值与先前写入的值相同。
没有其他用于volatile的东西 - 不,甚至在多线程中都没有(无论如何它都不会做你想要的)。
来自§7.1.6.1
[注意:volatile是实现的提示,以避免涉及对象的激进优化 因为对象的值可能会被实现无法检测的方式更改。此外, 对于某些实现,volatile可能表示需要访问特殊硬件指令 物体。有关详细语义,请参见1.9。通常,volatile的语义是有意的 在C ++中与在C中相同。 - 尾注]
这里的含义是,除非你完全理解实现对volatile变量的作用,否则你没有地方使用它。
它的使用是不可移植的,所以如果使用它,应该包含在你正在处理的任何概念的特定于实现的专门化中。
答案 1 :(得分:1)
如何简单地抛弃读取的波动性?
原来并不简单。
以下似乎只能在clang上可靠地运行。并且只有在执行volatile写操作之前创建hw_reg_read别名。
volatile int * hw_reg = (int*)0x0001003B;
int main()
{
/*obtain nonvolatile alias*/
int* hw_reg_read = const_cast<int*>(hw_reg);
/*volatile write*/
*hw_reg = 42;
/*nonvolatile read*/
int i = *hw_reg_read;
return i;
}
我现在将其作为稻草人留在这里。
答案 2 :(得分:0)
在较高级别,您可以使用智能指针,discussed here。
你正在谈论给某个变量另一个属性(至少)。如果变量具有给定属性,则在访问它时采取不同的操作(读或写)。
为此,您需要修改编译器。这是可能的。例如,8051编译器具有允许位访问和变量页访问的属性。许多嵌入式系统的编译器都具有将变量放在特定内存块中的语法。
我建议先尝试使用智能指针包装器。
另一个想法是将变量放入一个类中,并提供 getters 和 setters 来为您的环境建模(不允许直接访问)。
答案 3 :(得分:0)
我认为这可能就是我想要的:
template<class T>
class smartWriter{
volatile T* Volatile; //Use this for writes
T* NotVol; //Use this for reads
public:
smartWriter(T* add) : Volatile(add),NotVol(add){
}
operator T&() const{
return *NotVol; //reads involve the non volatile one
}
void operator=(T data){
*Volatile = data; //writes involve the volatile one
}
};
int main(int argc,char** args){
smartWriter<int> smtVar(((int*)0xdeadbeaf)) ; //Initialize var with address "0xdeadbeef"
smtVar = 12; //Optimizer can not get rid of this
int other = smtVar; //Optimizer might get rid of this?
system("Pause");
}
感谢用智能指针激发我的想象力......