What is the purpose of the "volatile" keyword appearing inside an array subscript? What is the purpose of the "volatile" keyword appearing inside an array subscript? c c

What is the purpose of the "volatile" keyword appearing inside an array subscript?


The volatile keyword is used to declare an array type of a function parameter.

Here, double x[volatile] is equivalent to double * volatile x.

The cppreference says :

In a function declaration, the keyword volatile may appear inside the square brackets that are used to declare an array type of a function parameter. It qualifies the pointer type to which the array type is transformed. The following two declarations declare the same function:

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

This syntax only valid in C language in function parameters.


In general, this C (and C only!) feature allows to specify any type qualifier inside the array brackets; the exact standard quotation is:

A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

(C99, §6.7.5.3, ¶7, emphasis added)

This means that this is not just limited to volatile, but const and restrict are allowed as well (see Type qualifiers, §6.7.3 ¶1).

The point of this hack is essentially to let you add a type qualifier to the parameter (not to the element of the array) and still retain the array syntax for the declaration; without this syntax, you are forced to fall back to writing it out as a pointer (which is what it boils down to anyway except for the static case, which AFAIK doesn't have an equivalent pointer syntax).

I suspect that the idea is mostly to make the syntax slightly less awkward for multidimensional arrays; quoting §6.7.5.3 ¶21:

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

are all equivalent, but 2 and 3 may convey slightly better that this is not intended just a pointer, but an array, and still allowing some place to put the restrict qualifier.

Also, as said above, there seem to be no way to have something like

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

(which "also specifies that the argument corresponding to a in any call to f must be a non-null pointer to the first of at least three arrays of 5 doubles", ibidem) with the "regular" pointer syntax.

Still, I'd stay away from this syntax; it's extremely obscure, rarely used (I don't think I ever needed to add a type qualifier to an array parameter - again, the parameter itself, not the element type; restrict is the only use case that can make sense) - and not portable to C++ (which is generally relevant if you are writing a library).