volatile in c99

[after non-response in clc,] [multi-posted to:] [comp.std.c] [comp.arch.embedded]

By trade, I'm a carpenter, and I've been implementing a greener heating solution for the house I'm flipping including fans that are to be controlled by an integrated circuit. I expect this solution to help the house, help the planet, and put more green in my wallet.

It is in the programming for, say, a thermistor, that volatile comes into play. I thought of doing the whole project in C, which, I thought, was the best tool for this type of thing. I've now stumbled upon an opinion that volatile in C99 is not a good thing, and now I have a couple questions.

q1) Is there anybody around with a serious criticism of volatile in C99?

q2) What changed about volatile between C90 and C99?

I have 1256.pdf on my machine now. Thanks for your comment.

--
George

Everywhere that freedom stirs, let tyrants fear.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Reply to
George
Loading thread data ...

AFAIK, the only change was (from the Rationale)

"A new feature of C99: The static storage class specifier and any of the type-qualifiers, restrict, const or volatile, can appear inside the [ and ] that are used to declare an array type, but only in the outermost array type derivation of a function parameter."

which is hardly likely to affect your use of volatile to decorate A/D registers.

The "restrict" keyword was added, which necessitated some wording changes in the paragraphs discussing const, volatile, and restrict.

I am not a language lawyer; it will be interesting to read the discussion.

What prompted the original question/concern?

--
Rich Webb     Norfolk, VA
Reply to
Rich Webb

(Don't multi-post - if the post is on-topic and of interest to several groups, the following discussion is also of interest. Multi-posting greatly irritates people who follow both groups, and those who haunt only one of the groups lose out on potentially interesting alternative viewpoints.)

I don't know about specific changes of "volatile" between C90 and C99, but there is plenty to criticise about "volatile" in C. Much of it is to do with programmers' misunderstandings and vague specifications in the standards. I'm sure I'll be corrected if I've misinterpreted the standards here!

It's too restrictive. You can't specify that a piece of data is "volatile" for writes but not for reads.

It doesn't correspond directly to what people think - in particular, people often mistakenly think "volatile" access implies atomic access.

It depends on sequence points, and everything between sequence points is only loosely specified. Consider this code:

extern volatile int va, vb; int foo(void) { return (va + vb + va); }

There is no requirement in the standard that says va must be read twice, or the order in which va and vb are read. The standard only says that access to volatile data must match up exactly to the expectations of the abstract machine at the sequence points. So between sequence points the compiler can read volatile data as often as it wants (either more often or less often than the source code implies), and it can write volatile data as often as it wants (as long as the final write is correct).

The compiler is free to remove code that accesses volatile data if it knows the code is unnecessary. In particular, if your source code reads volatile data but does not use the result, the compiler may eliminate the read.

Volatile access ordering only applies to volatiles - people often think that volatile accesses force the compiler to separate all code before and after the access. This is simply not true - volatile accesses at different sequence points must be ordered according to the source code, but other accesses and code can be reordered by the compiler. For example:

extern volatile int testPin; static void doSomething(void) { ... } static void timeSomething(void) { testPin = 1; doSomething(); testPin = 0; }

If the compiler knows that doSomething() does not have any volatile accesses, it is free to move the entire call before "testPin = 1" or after "testPin = 0".

Most people believe "volatile" means that the compiler should read or write the data exactly as specified in the source code, in the same order and with the same number of reads and writes. As far as I know, compilers normally implement "volatile" in exactly this way. But the standards give no guarantees.

Reply to
David Brown

(void) {

My understanding is that "volatile" just tells the compiler not to optimize out reads; the rest will be done as obscurely (or directly) a the optimizer is written.

So it is certainly the correct paradigm to use for reading an ADC. Usually I will declare something like this volatile, read it _once_ at each loop iteration, and get on with life.

--
Tim Wescott
Control systems and communications consulting
http://www.wescottdesign.com

Need to learn how to apply control theory in your embedded system?
"Applied Control Theory for Embedded Systems" by Tim Wescott
Elsevier/Newnes, http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

I did not know that... is it really true? It would seem to make reliable hardware access impossible. Since "Using the results" could usually be optimised out by a sufficiently "clever" compiler.

--

John Devereux
Reply to
John Devereux

Yes, it really is true and it is the reason for the volatile modifier.

--
========================================================================
          Michael Kesti            |  "And like, one and one don't make
                                   |   two, one and one make one."
    mrkesti at hotmail dot com     |          - The Who, Bargain
Reply to
Michael R. Kesti

No, David seems to be saying that even *with* the modifier, the compiler is still free to remove read accesses if the result is not used. This is contrary to what I have been assuming.

--

John Devereux
Reply to
John Devereux

I don't believe that David is correct. From a C standard:

[#2] Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,10) which are changes in the state of the execution environment. Evaluation of an expression may produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place. (A summary of the sequence points is given in annex C.)

The code:

volatile int x;

...

if (x) ;

or even:

x;

should generate a read access to x. Reason: side-effect.

The Lizard.

Reply to
Jujitsu Lizard

If you didn't get a response in c.l.c there is probably a reason, because that is the proper place for this enquiry. In addition, you have committed the sin of multi-posting. Don't do that. Instead, you could cross-post, and set follow-ups to your main newsgroup of interest. This will avoid annoying people in multiple newsgroups, and ensure that you see all replies in the one place.

--
 [mail]: Chuck F (cbfalconer at maineline dot net) 
 [page]: 
            Try the download section.
Reply to
CBFalconer

Oops. Yes, I agree your observation, John, and see that I failed to accurately interpret his statements.

It is contrary to how every C compiler I have used, too. The point of the volatile modifier is to prevent optimizers from removing code such as David describes.

--
========================================================================
          Michael Kesti            |  "And like, one and one don't make
                                   |   two, one and one make one."
    mrkesti at hotmail dot com     |          - The Who, Bargain
Reply to
Michael R. Kesti

Looking closer at it, I think you are basically right - "accessing" a volatile is considered a side-effect. I still do not think there are guarantees about accesses between sequence points (there is nothing to say whether two reads are two side-effects, or whether they can be combined - nor is any ordering implied). But it looks like a request to read volatile data must cause a real read even if the result is then ignored.

However, there is (AFAIK) no precise definition of "access". In particular, if you have a 16-bit volatile item on an 8-bit cpu, it is not clear when a volatile read forces a read of the whole 16 bits (two

8-bit accesses) and when the compiler can use a single 8-bit read. For example, will "if (x & 0x0001) ..." just read the low byte? The standard does say that compilers should perform according underlying hardware restrictions (for example, on the AVR access to the 16-bit timer registers must be done in a specific order).

See also:

And regarding C++ (which is not C99, of course, but still interesting):

In my experience, compilers have always generated volatile reads and writes based directly on the source code, as people expect them to. Just because the standards are not as clear as they should be, doesn't mean compilers don't do a good job!

Reply to
David Brown

I am not sure that is completely true, I don't think it is the standards intent. For quite a while we have been looking at developers intent in generating code. It this were true then va; could be eliminated in most if not all cases. We have taken the opinion that the developer had a specific reason for including the statement and we should retain it in the generated code.

In the data flow analysis of our compilers we mark volatile variables as with having an unknown value which forces at least a single read to occur between sequence points. Between sequence points we allow full optimization. This is consistent with both David and Tim's comments.

Regards

-- Walter Banks Byte Craft Limited

formatting link

Reply to
Walter Banks

That is certainly how compilers view "volatile". My point was about what the standards say, which is not nearly as well specified as what compilers actually *do*.

Reply to
David Brown

And you've committed the sin of posting without first reading other replies in this thread - I've already commented on multi-posting.

You also seem to misunderstand the concept of "follow-ups". This is Usenet, not a private help line for any given poster. If a thread is started as cross-posting to several groups, it should continue as cross-posting - if it were not of interest to all the groups, it should not have been posted to them in the first place. Setting a follow-up on the basis of one's personal group preferences is selfish - threads are here for the benefit and interest of everyone. Follow-ups are only appropriate for branches that are clearly relevant in only one group.

Reply to
David Brown

The timer thing is always awkward. I've always unioned it and done something like:

x.b[0] = TREGH; x.b[1] = TREGL;

if (x.w > 4922) etc.

But yeah, leaving the ordering decision to the compiler is generally not done.

I've never thought about the "skip the MSB" scenario, but one can concoct scenarios for skip the LSB as well ("if (x & 0xFF00)"). A good compiler WILL skip the access on a normal variable --- unclear what would be done for volatiles. Good point.

Some recent microcontrollers have caught my attention because they allow accesses in either order for the latching logic on 16-bit registers. I'm not sure that that is a good thing. It may just allow an inexperienced programmer to get further before his project blows up with intermittent bugs because he never read the data book closely enough to know that there was latching logic at all.

Reply to
Jujitsu Lizard

Thanks all for responses. It looks like compilers do what you'd expect, while the C standard doesn't specify all that well what that is.

I'd just gone over the use of volatile with a couple of threads here about "computer driven fans," so I thought I was all straightened out on it.

One of the things that came out of the fortran enclave in tokyo is that volatile in C is under-defined. Those who responded missed nothing from the multi-post in comp.std.c, which drew no response.

I like the monday after Thanksgiving. It's Christmas season.

--
George

The momentum of freedom in our world is unmistakable - and it is not
carried forward by our power alone. We can trust in that greater power Who
guides the unfolding of the years. And in all that is to come, we can know
that His purposes are just and true.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Reply to
George

You failed to address the question of what someone should do on a reply if the OP's choice of groups was dubious.

In other words, you're assuming that the original choice of groups was sane. It may not have been.

The Lizard

Reply to
Jujitsu Lizard

I've assumed that the original poster felt the choice of groups was sane, and should therefore not set follow-ups. Others replying to that post might disagree and then set follow-ups - that makes a specific branch.

Reply to
David Brown

And you fail to understand the purpose of a cross-post. It is to attract the attention of people who may not be watching the primary group in the first place. Once attracted, there is no need to maintain the cross-post, since if they have any brains and so wish they can simply attend the primary group for the period of the thread. If they really wish to annoy they can cancel the follow-up, or part of it. However the cross-post with follow-up generally prevents foolish posts by idiot trolls whose only objective is to harm the newsgroup.

--
 [mail]: Chuck F (cbfalconer at maineline dot net) 
 [page]: 
            Try the download section.
Reply to
CBFalconer

Yes, I'm *sure* that people will join other groups just to help out on other particular threads.

Back here in the real world, there are reasons people choice particular groups to follow, and don't bother with other groups. I'm not interested in the vast majority of threads in c.l.c or c.s.c - but I

*am* interested in threads that are relevant to both c.a.e. and one of these groups. I am also interested in what people from these different groups have to say to each other within a relevant thread. But neither I nor 99% of the other Usenet regulars are going to join a different group for a one-off thread - without the cross-group participation, it would not be nearly as interesting. For example, a C standards discussion on "volatile" would be of little interest to me without an embedded slant and input from embedded developers.
Reply to
David Brown

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.