当我浏览cppreference时,我在函数参数中看到了一个奇怪的类型数组,如下所示:
void f(double x[volatile], const double y[volatile]);
那么,volatile
关键字出现在数组下标中的目的是什么?它做了什么?
答案 0 :(得分:39)
volatile
关键字用于声明函数参数的数组类型。
此处,double x[volatile]
相当于double * volatile x
。
在函数声明中,关键字
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
,还允许const
和restrict
(请参阅类型限定符,§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 ++(如果你正在编写一个库,这通常是相关的)。