在c ++中void * volatile *的含义是什么?

时间:2014-11-28 03:48:08

标签: c++ pointers volatile qualifiers

我正在查看以下代码:

inline void* interlocked_read_acquire(void* volatile* x);

我想知道为什么不只是volatile void*作为参数。一般来说volatile*的语义或定义是什么?我也假设您可以将volatile*限定符与除void之外的任何其他类型一起使用。这是对的吗?

4 个答案:

答案 0 :(得分:20)

使用cdeclclockwise spiral rule解密C风格的声明:

void* volatile* x
  • 将x 声明为指向void
  • 的易失性指针

不同于:

volatile void* x
  • 将x 声明为指向volatile void
  • 的指针

答案 1 :(得分:10)

  

想知道为什么[void* volatile*和]不只是volatile void* ......?

他们是不同的东西。

  • void* volatile*是一个指向volatile(void*)的指针(因此可以在不进行转换的情况下取消引用和访问volatile void*,但只会给你一些地址作为 - 内存中未指明的东西)

  • volatile void*是指向易变void的指针(因此您必须在解除引用前强制转换为类似volatile int*volatile My_Class*的类型)

答案 2 :(得分:7)

void * ptr1;表示ptr1是类型为void *的变量。此类型表示“通用指针” - 它指向某个内存位置,但不包含该位置内的类型信息。

void * volatile ptr2;表示变量ptr2也是通用指针,但ptr2也是volatile。关键字volatile称为 cv-qualifier ,它与const具有相同的语法规则。

volatile变量的含义是,当其他一些代码表示ptr2时,编译器无法对其进行优化;它必须读取或写入存储ptr2的存储位置;它必须允许某些外部过程也在读取或写入该位置。

最后,void * volatile *x可以指向ptr2。例如,我们可以void * volatile * x = &ptr2;。如果我们以*x = NULL;为例,那么*x的类型void * volatile与我们刚才查看的ptr2具有相同的含义。

如果您省略了限定符,编译器会抱怨,例如void * *y = &ptr2;。这是因为表达式*y将具有类型void *(非易失性),因此编译器可能会围绕它执行优化,但这是不正确的行为,因为ptr2不允许这些优化。 (您可能会认识到“volatile-correctness”与const-correctness相同)。

答案 3 :(得分:-1)

volatile是一个附加属性,你可以先删除它来读取

var RECURRING_KEY = "recurring";
var ARGUMENTS_KEY = "arguments";

/**
 * Sets up the arguments for the given trigger.
 *
 * @param {Trigger} trigger - The trigger for which the arguments are set up
 * @param {*} functionArguments - The arguments which should be stored for the function call
 * @param {boolean} recurring - Whether the trigger is recurring; if not the 
 *   arguments and the trigger are removed once it called the function
 */
function setupTriggerArguments(trigger, functionArguments, recurring) {
  var triggerUid = trigger.getUniqueId();
  var triggerData = {};
  triggerData[RECURRING_KEY] = recurring;
  triggerData[ARGUMENTS_KEY] = functionArguments;

  PropertiesService.getScriptProperties().setProperty(triggerUid, JSON.stringify(triggerData));
}

/**
 * Function which should be called when a trigger runs a function. Returns the stored arguments 
 * and deletes the properties entry and trigger if it is not recurring.
 *
 * @param {string} triggerUid - The trigger id
 * @return {*} - The arguments stored for this trigger
 */
function handleTriggered(triggerUid) {
  var scriptProperties = PropertiesService.getScriptProperties();
  var triggerData = JSON.parse(scriptProperties.getProperty(triggerUid));

  if (!triggerData[RECURRING_KEY]) {
    deleteTriggerByUid(triggerUid);
  }

  return triggerData[ARGUMENTS_KEY];
}

/**
 * Deletes trigger arguments of the trigger with the given id.
 *
 * @param {string} triggerUid - The trigger id
 */
function deleteTriggerArguments(triggerUid) {
  PropertiesService.getScriptProperties().deleteProperty(triggerUid);
}

/**
 * Deletes a trigger with the given id and its arguments.
 * When no project trigger with the id was found only an error is 
 * logged and the function continues trying to delete the arguments.
 * 
 * @param {string} triggerUid - The trigger id
 */
function deleteTriggerByUid(triggerUid) {
  if (!ScriptApp.getProjectTriggers().some(function (trigger) {
    if (trigger.getUniqueId() === triggerUid) {
      ScriptApp.deleteTrigger(trigger);
      return true;
    }

    return false;
  })) {
    console.error("Could not find trigger with id '%s'", triggerUid);
  }

  deleteTriggerArguments(triggerUid);
}

/**
 * Deletes a trigger and its arguments.
 * 
 * @param {Trigger} trigger - The trigger
 */
function deleteTrigger(trigger) {
  ScriptApp.deleteTrigger(trigger);
  deleteTriggerArguments(trigger.getUniqueId());
}

function example() {
  var trigger = ScriptApp.newTrigger("exampleTriggerFunction").timeBased()
    .after(5 * 1000)
    .create();

  setupTriggerArguments(trigger, ["a", "b", "c"], false);
}

function exampleTriggerFunction(event) {
  var functionArguments = handleTriggered(event.triggerUid);
  console.info("Function arguments: %s", functionArguments);
}

为:

void* volatile* x

这非常熟悉。例如,malloc-ed内存指针数组。 你不会对

感到困惑
void* *x

减少到

volatile void*