msc*_*msc 43 c arrays volatile function-parameter
当我浏览cppreference时,我在函数参数中看到了一个奇怪的类型数组,如下所示:
void f(double x[volatile], const double y[volatile]);
Run Code Online (Sandbox Code Playgroud)
那么,volatile关键字出现在数组下标中的目的是什么?它有什么作用?
msc*_*msc 40
该volatile关键字用于声明函数参数的数组类型.
在这里,double x[volatile]相当于double * volatile x.
该cppreference说:
在函数声明中,关键字
volatile可能出现在方括号内,用于声明函数参数的数组类型.它限定了数组类型转换的指针类型.以下两个声明声明了相同的函数:Run Code Online (Sandbox Code Playgroud)void f(double x[volatile], const double y[volatile]); void f(double * volatile x, const double * volatile y);
此语法仅在函数参数的C语言中有效.
Mat*_*lia 14
通常,此C(和C only!)功能允许在数组括号内指定任何类型限定符; 确切的标准报价是:
一个参数为""类型的阵列""的声明,应调整至""合格指针为类型"",其中类型限定符(如果有的话)的那些内的指定
[和]该阵列类型的推导.如果关键字static也出现在数组类型派生的[和]中,那么对于每次对函数的调用,相应的实际参数的值应该提供对数组的第一个元素的访问,其中至少有与该大小指定的元素一样多的元素.表达.
(C99,§6.7.5.3,7,重点补充)
这意味着,这并不仅仅局限于volatile,但const和restrict也是允许的(见类型修饰符,§6.7.31).
这个hack的要点主要是让你为参数添加一个类型限定符(而不是数组的元素),并且仍然保留声明的数组语法; 如果没有这种语法,你将被迫退回到将其作为指针写出来(除了static案例,AFAIK没有等效的指针语法之外,它无论如何都会归结为它).
我怀疑这个想法主要是为了使多维数组的语法略显笨拙; 引用§6.7.5.321:
void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
Run Code Online (Sandbox Code Playgroud)
都是等价的,但是2和3可能稍微好一点,这不仅仅是一个指针,而是一个数组,并且仍然允许一些地方放置restrict限定符.
而且,如上所述,似乎没有办法有类似的东西
void f(double a[restrict static 3][5]);
Run Code Online (Sandbox Code Playgroud)
("还指定a在任何调用中对应的参数f必须是指向至少三个5个双精度数组中的第一个的非空指针",ibidem),带有"常规"指针语法.
不过,我会远离这种语法; 它非常模糊,很少使用(我认为我不需要在数组参数中添加类型限定符- 再次,参数本身,而不是元素类型; restrict是唯一可以理解的用例) - 并且不可移植到C++(如果你正在编写一个库,通常是相关的).