Is there any practical difference between the following prototypes?
void f(const int *p);
void f(const int *restrict p);
void f(const int *volatile p);
The presence of a top-level volatile
qualifier applied to a parameter in a function's definition may cause behavior to be defined in some cases where it otherwise would not. Most notably:
int test(int volatile x)
{
if (setjmp(&someJumpBuff)) return x;
x++;
someFunction(); // A function that calls longjmp(&someJumpBuff, 1);
x--;
return x;
}
If x
were not declared volatile
, a compiler could optimize out the x++
and x--
since it could assume that no other code would ever examine the value of x
between those two operations. The volatile
declaration, however, would force the compiler to presume that code which examines x
after the setjmp
might execute between the x++
and x--
and thus observe the value x
held at that time.
It may be possible to contrive a platform calling convention where a "clever" optimizer that knew nothing about a function's definition beyond the fact that it did not use a volatile
qualifier on an argument would be able to generate code that would not be allowable in the presence of such a qualifier, but even on such a platform, a compiler that only saw that a function's prototype lacked a volatile
qualifier would have no basis for assuming that its definition wouldn't include one.