-
April 4th, 2010, 12:52 AM
#1
volatile functions?
I will probably ask this again in a year, but what is the purpose of using volatile in the case of volatile functions? With data it makes sense as I envision the compiler putting variables into registers and re-using them at will -- so I want volatile if I expect other processes to be modifying this data, hence telling the compiler not to cache this variable as it could be invalid. That's pretty much the only example of volatile I understand. So what's the difference when it comes to functions?
-
April 4th, 2010, 12:59 AM
#2
Re: volatile functions?
I don't recommend using the volatile keyword. Most people who try to use it assume it's a synchronization mechanism, and it really isn't.
I doubt it does much of anything to functions, except to mark them as only callable from a volatile object (but then, non-primitive objects being volatile doesn't really mean anything either). The type system treats it similarly to const, although like const, it has little effect on the generated code when assigned to a non-primitive.
I saw one article which argued for using volatile to help enforce multithreaded safety, but that was mainly a matter of leveraging a little-used keyword to hack the type system; the normal behavior of the volatile keyword didn't enter into it. While an interesting concept, ultimately I think going that route is probably a bad idea.
-
April 4th, 2010, 01:02 AM
#3
Re: volatile functions?
Originally Posted by andersod2
So what's the difference when it comes to functions?
link
Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
Convenience and productivity tools for Microsoft Visual Studio:
FeinWindows - replacement windows manager for Visual Studio, and more...
-
April 4th, 2010, 02:39 AM
#4
Re: volatile functions?
So it's a qualifier for a class member function? Then why do compilers let you declare regular static C-style functions as volatile? Actually, now that I think about it, I still don't even understand what it means as as class member function qualifier -- the link is comparing it to const member functions, but const actually means something specific in that context. How does qualifying a member function as volatile affect the operation of the function? (i.e. it treats all data accesses in the function as though they were all volatile?)
-
April 4th, 2010, 02:46 AM
#5
Re: volatile functions?
Originally Posted by andersod2
Then why do compilers let you declare regular static C-style functions as volatile?
They do? I tested with this program:
Code:
void foo() volatile {}
int main() {}
The Comeau online compiler reports:
Code:
"ComeauTest.c", line 1: error: type qualifier is not allowed on this function
void foo() volatile {}
^
The MinGW port of g++ 3.4.5 reports:
Code:
error: non-member function `void foo()' cannot have `volatile' method qualifier
With and without language extensions enabled, MSVC9 reports:
Code:
error C2270: 'foo' : modifiers not allowed on nonmember functions
-
April 4th, 2010, 03:13 AM
#6
Re: volatile functions?
Originally Posted by andersod2
How does qualifying a member function as volatile affect the operation of the function? (i.e. it treats all data accesses in the function as though they were all volatile?)
volatile qualifier states that the member should be used with a volatile object(when used all the member variables will become volatile as well), that can be useful if you have a set of functions which are thread-safe, and another set which is not.
So you can design your class so that the thread-safe functions decleared with volatile qualifier, and if you want an object of that class to be manipulated with threads or processes you will declear it as volatile(by the way you will of course have to use thread synchronization mechanisms as well).
for example you can use this class:
Code:
template<class T>
class Counter
{
private:
T count;
public:
void increment() volatile
{
// Call it for volatile objects
InterlockedIncrement(&count);
};
void increment()
{
// call it for non-volatile objects
++count;
};
};
You can overload the volatileness of the function, and when you use a volatile object and call push that will be thread safe, otherwise it will not be so.
[EDITED THE MESSAGE]
Last edited by Regel; April 4th, 2010 at 03:43 AM.
-
April 4th, 2010, 06:24 AM
#7
Re: volatile functions?
Ok, that is making a bit more sense, thanks --
laserlight try putting the volatile at the beginning -- that works for me on VS2008, and cygwin gcc. Still not sure what that means.
-
April 4th, 2010, 06:56 AM
#8
Re: volatile functions?
Originally Posted by andersod2
Ok, that is making a bit more sense, thanks --
laserlight try putting the volatile at the beginning -- that works for me on VS2008, and cygwin gcc. Still not sure what that means.
it seems weird that it works for void, but anyway if you put it in the beginning it means you return a volatile value, which can't be optimized by the compiler.
Last edited by Regel; April 4th, 2010 at 07:00 AM.
-
April 4th, 2010, 06:58 AM
#9
Re: volatile functions?
Originally Posted by andersod2
laserlight try putting the volatile at the beginning -- that works for me on VS2008, and cygwin gcc. Still not sure what that means.
Code:
volatile int foo();
This declares a function called foo, which returns a volatile int. The keyword volatile has no bearing on the function in this case, just on the return type.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
April 4th, 2010, 08:26 AM
#10
Re: volatile functions?
Regel's example is using the "hacking the type system" approach which I previously said I considered a bad idea. It has nothing to do with the meaning of the volatile keyword, it's just exploiting the fact that "volatile" is part of the type system.
I'd think it was a great idea if there were a keyword dedicated to the purpose, but coopting another keyword just to try and enforce compile-time thread safety seems dicey.
-
April 4th, 2010, 05:45 PM
#11
Re: volatile functions?
forgive my dense-ness, but I still don't understand how a return value of volatile fits into the basic scenario I described above for volatile data. In other words, if I have a return value from a function I'm going to put it into a variable or otherwise be passing it into another function right away...how can that value be cached into a register in some undesirable way without first being put into another variable (which may or may not be volatile)...? sorry i'm just not in a thinking mood today...happy easter...
-
April 4th, 2010, 06:10 PM
#12
Re: volatile functions?
Originally Posted by andersod2
forgive my dense-ness, but I still don't understand how a return value of volatile fits into the basic scenario I described above for volatile data. In other words, if I have a return value from a function I'm going to put it into a variable or otherwise be passing it into another function right away...how can that value be cached into a register in some undesirable way without first being put into another variable (which may or may not be volatile)...? sorry i'm just not in a thinking mood today...happy easter...
Let's say you have a function of the signature - bool& Wait() and it returns a bool that can be changed at any time during the execution. And you have a while loop:
Code:
while(Wait()) // another thread may change the bool referent.
{
...
}
The compiler can transform it into the following assembly instructions:
Code:
call check ; ax = return value(address of a bool value)
mov ax, [ax] ; dereference the bool, only once
lp:
cmp ax, 1
jz lp ; can be an infinite loop!
Now, for a single-threaded application that may be a legitimate and a good optimization, whereas for a multi-threaded application it is not correct - because the reference returned from the function can be changed at any time.
You always read the same value of the ax register, what volatile gives you is a prevention of such compiler optimization.
By changing the function so it returns volatile value we force the compiler to generate the following code:
Code:
call check
lp:
cmp [ax], 1 // always read the memory location(no optimzation pitfalls!)
jz lp
Hope you now have a good understanding of what volatile keyword really do, it is simple and useful.
Last edited by Regel; April 4th, 2010 at 06:16 PM.
-
April 4th, 2010, 06:16 PM
#13
Re: volatile functions?
I don't think that's a great example, since it would be foolish to expose a reference to a variable modified in multiple threads. Rather, it would make a lot more sense to keep the accesses requiring synchronization locks confined to one place, and have Wait() return a copy of the value.
While I understand in principle what volatile does, I've yet to encounter a need for it in a well-designed multithreaded program.
-
April 4th, 2010, 06:56 PM
#14
Re: volatile functions?
Well it's a great starting example of how volatile would be necessary as a function return (thanks Regel). I would agree that such a scenario could be designed better, but if I were in charge of fixing a bug with that code I may not have redesigned for fear of mucking with stable code -- I would just add "volatile" to the return value and be done with it.
So what I am understanding now (and will forget in a year) is this return modifier is basically just ensuring that data (which is already volatile) keeps it's volatile nature when a reference to that data is being used.
However, in the first non-volatile example above the check/Wait() function is only being called once...wouldn't it be getting called for every pass of the loop, thus forcing the dereference of ax each time? (i.e. giving us what we want without using volatile)...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|