Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么时候需要在Ruby C扩展中声明可变值?_C++_C_Ruby_Garbage Collection_Mark And Sweep - Fatal编程技术网

C++ 什么时候需要在Ruby C扩展中声明可变值?

C++ 什么时候需要在Ruby C扩展中声明可变值?,c++,c,ruby,garbage-collection,mark-and-sweep,C++,C,Ruby,Garbage Collection,Mark And Sweep,我找不到太多的文档说明什么时候应该在Ruby扩展中将值声明为volatile,以避免对正在使用的对象进行过早的垃圾收集 这是我到目前为止学到的。有人能填空吗 当不需要使用volatile时: C++对象成员中的LI>(因为它们从不在堆栈上) 在不调用Ruby API的C/C++方法中(因为在调用Ruby API之前GC不会打开) 当确实需要使用volatile时 在C/C++方法中,调用任意RubyALLOC或malloc宏/函数(因为这些宏/函数在内存高度碎片化时会触发GC) 在调用任何

我找不到太多的文档说明什么时候应该在Ruby扩展中将
值声明为
volatile
,以避免对正在使用的对象进行过早的垃圾收集

这是我到目前为止学到的。有人能填空吗

当不需要使用
volatile
时:
    C++对象成员中的LI>(因为它们从不在堆栈上)
  • 在不调用Ruby API的C/C++方法中(因为在调用Ruby API之前GC不会打开)
当确实需要使用
volatile
  • 在C/C++方法中,调用任意Ruby
    ALLOC
    malloc
    宏/函数(因为这些宏/函数在内存高度碎片化时会触发GC)
  • 在调用任何Ruby函数的C/C++方法中(例如,
    rb_funcall
    rb_ary\u new
    ,等等)
避免GC的其他方法
  • 标记正在使用的
  • 在对象创建期间禁用GC,然后重新启用它
  • 不要使用Ruby的分配方法(有风险)

一切都对吗?我遗漏了什么细节?除了标记之外,
volatile
是唯一的方法吗?

将变量标记为
volatile
可以防止C/C++编译器基于变量不能“自行”更改值的假设应用某些优化


我认为在C扩展以外的Ruby代码共享或可以更改
值时应该使用它,以使编译器意识到这一事实。看看。

我认为经验法则是,如果您的变量值可以在运行时的任何时候更改,并且您不知道何时更改,请使用
volatile
关键字。这包括中断。例如,您有一个中断回调函数,它计算用户在键盘上按下某个键的次数。您的程序不知道用户何时按下键盘上的按钮,因此必须使用
volatile
关键字声明计数器变量

如前所述,它禁用了对变量的一些编译器优化。例如:

int a = 5;
while(a == 5){
  //do something
}
编译器将
while(a==5)
语句优化为
while(true)
,因为它发现变量a在运行时不能更改,并且在每个循环中检查
a
的值是没有用的。所以你最终进入了一个无限循环。但是如果添加关键字
volatile

volatile int a = 5;
while(a == 5){
  //do something
}

您只需告诉编译器让变量保持原样。不要对它进行任何优化,一些中断可能会改变它的值。在这一点上,它工作得很好。

这是一种误导。在C和C++中,波动性不同。