“volatile”关键字出现在数组下标中的目的是什么?

时间:2017-11-19 12:57:23

标签: c arrays volatile function-parameter

当我浏览cppreference时,我在函数参数中看到了一个奇怪的类型数组,如下所示:

void f(double x[volatile], const double y[volatile]);

那么,volatile关键字出现在数组下标中的目的是什么?它做了什么?

2 个答案:

答案 0 :(得分:39)

volatile关键字用于声明函数参数的数组类型。

此处,double x[volatile]相当于double * volatile x

cppreference说:

  

在函数声明中,关键字volatile可能会出现在   方括号,用于声明函数的数组类型   参数。它限定数组类型所针对的指针类型   转化。以下两个声明声明了相同的函数:

void f(double x[volatile], const double y[volatile]);

void f(double * volatile x, const double * volatile y);

此语法仅在函数参数的C语言中有效。

答案 1 :(得分:14)

通常,此C(和C only!)功能允许在数组括号内指定任何类型限定符;确切的标准报价是:

  

参数声明为''数组类型''应调整为''限定指针   类型'',,其中类型限定符(如果有)是在[]内指定的类型限定符。   数组类型推导。如果关键字static也出现在[]内   数组类型派生,然后对每个函数调用,对应的值   实际参数应提供对至少具有至少数量的数组的第一个元素的访问   由size表达式指定的元素。

(C99,§6.7.5.3,¶7,重点补充)

这意味着这不仅限于volatile,还允许constrestrict(请参阅类型限定符,§6.7.3 ¶1)。

这个hack的要点主要是让你将类型限定符添加到参数到数组的元素)并仍保留数组语法宣言;如果没有这种语法,你将被迫退回到将其作为指针写出来(除了static案例之外,它总是归结为,而AFAIK没有等效指针语法)。

我怀疑这个想法主要是为了使多维数组的语法略显笨拙;引用§6.7.5.3¶21:

void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);

都是等价的,但是2和3可能稍微好一点,这不仅仅是一个指针,而是一个数组,并且仍然允许一些地方放置restrict限定符。

另外,如上所述,似乎没有办法像

那样
void f(double a[restrict static 3][5]);

(“还指定在a的任何调用中对应于f的参数必须是指向至少三个5个双精度数组中的第一个的非空指针”, ibidem )使用“常规”指针语法。

但是,我仍然远离这种语法;它非常模糊,很少使用(我认为我不需要将类型限定符添加到数组参数 - 再次,参数本身,而不是元素类型; restrict是只使用有意义的用例) - 并且不能移植到C ++(如果你正在编写一个库,这通常是相关的)。