Products > Programming
C functions with "volatile" return types - what does it mean?
westfw:
I was reading some freeRTOS documentation, and came across:
--- Code: ---volatile TickType_t xTaskGetTickCount( void );
--- End code ---
I don't think I understand what "volatile" does here, in the function definition.
A web search did not turn up any clear answers, except to clarify that this means that it is the return type (TickType_t) that is volatile, not "the function."
But I don't understand what it means for a return value to be "volatile." Return values are almost exclusively put in some register, and they're effectively "frozen" from that point on.
I suppose that this could prevent optimization from eliding multiple calls to the function:
--- Code: --- x = xTaskGetTickCount();
y = xTaskGetTickCount(); // yes, REALLY call the function again!
--- End code ---
Except that I thought that that was default behavior for function calls, perhaps overrideable with "pure" and "const" attributes (at least in gcc. Attributes are non-standard.)
Is a volatile return type just the opposite of the const attribute, enshrined in standardization? Does it mean that at some point function return types WON'T be volatile by default? (that will break a lot of things, I think.) Does the optimization it's trying to prevent happen only when functions are in-lined? (and if so, isn't that redundant if the function body accesses volatile variables?)
SiliconWizard:
Yes that would qualify the return type.
I tried thinking of contexts in which it could make a difference, but couldn't find any.
- If the function is defined in the same compilation unit, then whatever happens inside it will matter (as to whether it will be actually called or not) rather than its return type being qualified volatile or not.
- If it's defined externally, then it will get called unconditionally anyway, as the compiler can't know what the side-effects inside of it could be.
So, I don't think it has any practical purpose. Maybe it's in their "coding style" to match the return type exactly with the expression that is returned, although again here that shouldn't make any difference in terms of compiled code.
What I mean is:
xTaskGetTickCount() probably returns a global variable that is qualified volatile (a tick counter). So possibly their coding style requires the return type to match the returned expression, qualifiers included.
Just a guess. That may not be the rationale, but I know they have strict coding guidelines.
Now if anyone can find any real example of it making a difference, I'm all ears. I may have missed it.
radiolistener:
I think it is likely marked as volatile to ensure that the compiler does not omit calls to xTaskGetTickCount() for optimization purposes, even if it assumes that the function xTaskGetTickCount() code will return the same value.
westfw:
(Apparently this function is not really volatile; it seems to be a documentation error.)
TheCalligrapher:
--- Quote from: westfw on October 07, 2024, 12:11:49 am ---But I don't understand what it means for a return value to be "volatile."
--- End quote ---
What language are we talking here? C or C++?
In C language it means absolutely nothing. In C the return value is an rvalue and C does not support cv-qualification of rvalues. Meaning that you can legally apply such qualification in the source code, but it will be ignored anyway.
It is all natural aside from one corner case, which exists since C99: when the returned object is a struct with an array inside.
--- Code: ---#include <stdio.h>
volatile struct S { int a[5]; } foo(void)
{
return (struct S) { { 1, 2, 3, 4, 5 } };
}
int main()
{
int *p;
p = foo().a + 2, printf("%d\n", *p);
}
--- End code ---
Should the compiler complain about a pointer to non-volatile trying to point to a volatile object? The standard says that the answer is still the same: the cv-qualificatin of the returned value is ignored, so there's no violation in the above example.
Navigation
[0] Message Index
[#] Next page
Go to full version