是否使用易读参考保证,读操作不会被重新排序?

时间:2015-10-09 13:38:03

标签: c++ reference volatile

假设有一个$( "#outer-div" ).resizable({ containment: "#another-outer-div", minWidth: 200, minHeight: $('#inner-div').height(), start: function(event,ui) { var myMinHeight = $('#inner-div').height(); $( "#outer-div" ).resizable( "option", "minHeight", myMinHeight ); }, resize: function(event, ui) { ui.size.width += (ui.size.width - ui.originalSize.width); $(this).position({ of: $("#another-outer-div"), my: "center center", at: "center center" }) } }); 指向SHMEM中的某个地址。 char* buffer的第一个和第二个8字节在缓冲区中包含相应的buffercounter1无符号64位整数,其中counter2长度为message。现在让我们看看以下两段代码:

第一

n

第二

uint64_t counter1 = *((uint64_t*)(buffer));
memcpy(buffer_for_message, buffer + 2 * sizeof(uint64_t), n);
uint64_t counter2 = *((uint64_t*)(buffer)+1);

问题:

  1. 在第一段代码的情况下,处理器的volatile uint64_t& counter1_ref = *((uint64_t*)(buffer)); volatile uint64_t& counter2_ref = *((uint64_t*)(buffer)+1); uint64_t counter1 = counter1_ref; memcpy(buffer_for_message, buffer + 2 * sizeof(uint64_t), n); uint64_t counter2 = counter2_ref; counter1counter2读取内存块的顺序是否未定义?
  2. 如果第一个问题的答案是"是",第二个代码是否定义了订单(即message,那么counter1然后message )?

2 个答案:

答案 0 :(得分:3)

我认为,即使是第一种情况也会定义订单。这就是原因。

  • 编译器无法对这些指令重新排序,因为它们之间存在对memcpy()的调用。当然,memcpy可能是固有的,但在这种情况下,它应该看到相同的内存区域受到影响。
  • 由于缓冲区位于共享内存中,因此CPU不会重新排序。

但是,这两个示例都存在问题 - 违反严格的别名规则。

答案 1 :(得分:3)

根据C ++标准,

volatile本身与重新排序无关。有些编译器在使用volatile时提供获取和释放语义作为扩展,但这是非标准的。