我正在查看以下代码:
inline void* interlocked_read_acquire(void* volatile* x);
我想知道为什么不只是volatile void*
作为参数。一般来说volatile*
的语义或定义是什么?我也假设您可以将volatile*
限定符与除void之外的任何其他类型一起使用。这是对的吗?
答案 0 :(得分:20)
使用cdecl或clockwise spiral rule解密C风格的声明:
void* volatile* x
不同于:
volatile void* x
答案 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*