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

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可能出现在方括号内,用于声明函数参数的数组类型.它限定了数组类型转换的指针类型.以下两个声明声明了相同的函数:

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

void f(double * volatile x, const double * volatile y);
Run Code Online (Sandbox Code Playgroud)

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

  • C++语法比我想象的更没意义,我认为我们只是达到了丑陋的新高度.我在此建议禁止参加WG21会议. (27认同)
  • @MatteoItalia这不是C++语法. (10认同)
  • @hvd:我的建议随后将被发送到WG14. (8认同)
  • @MatteoItalia:C提供了更多的丑陋,因为规则有一个例外:给定`int foo(int myArray [static 5])`,`static`限定符并不意味着数组是静态的,而是保证所有的编译器可以假定来自`myArray [0]`..`myArray [4]`的存储是可读的而没有副作用. (6认同)
  • @supercat实际上,保证是指向数组元素的`x`指针,而表达式`x [0]`到`x [4]`表示同一数组的其他元素(即它们不读出该数组的界限)数组).术语"副作用"在C中具有特定含义 (3认同)

Mat*_*lia 14

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

一个参数为""类型的阵列""的声明,应调整至""合格指针为类型"",其中类型限定符(如果有的话)的那些内的指定[]该阵列类型的推导.如果关键字static也出现在数组类型派生的[]中,那么对于每次对函数的调用,相应的实际参数的值应该提供对数组的第一个元素的访问,其中至少有与该大小指定的元素一样多的元素.表达.

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

这意味着,这并不仅仅局限于volatile,但constrestrict也是允许的(见类型修饰符,§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++(如果你正在编写一个库,通常是相关的).

  • @edmz:`volatile`*参数*绝对是奇怪的......`volatile`意味着编译器应该保持警惕,存储在那里的值可能会在他的背后发生变化(例如由于中断处理程序,信号或其他硬件); 这通常是在多个actor之间共享的东西(例如某些全局变量)或硬件/ OS已知的内存中固定位置的东西; 根据定义,参数对于函数来说是局部的,所以我真的不知道`volatile`在这里有什么样的用处. (3认同)