const, volatile, etc

Doug Gwyn gwyn at smoke.BRL.MIL
Fri Dec 2 05:34:16 AEST 1988


In article <10919 at ulysses.homer.nj.att.com> ggs at ulysses.homer.nj.att.com (Griff Smith) writes:
>I blew several hours discovering that a flag set by a signal handler
>had been optimized out of existence because it wasn't declared volatile.

>If I were writing new software I would be
>aware of the problem and use the proper declaration, but what am I to
>do about fixing all the old stuff that now has subtle errors caused by
>optimizations that used to be illegal?

Aggressive optimization is the new wave, brought on partly by all those
C compiler races published in hobbyist magazines.  Most of the time,
faster-running code is an advantage, so generally this is a good thing.

>The response I got from a C++ guru around here wasn't encouraging: he
>suggested declaring everything volatile and ignoring the issue.

Maybe he was joking?

>Maybe he's right, but that attitude could easily lead to a habit of
>forcing all declarations to include the volatile qualifier just to
>avoid a `silly' rule.

No, that's not the proper way to use "volatile".  The only time you
need to use it is when there is a violation of the abstract C machine
model of sequential computation (where objects retain the value stored
into them until the next explicit store into them).  The two main
categories of exceptions to this model are variables shared with
interrupt handlers, as you noticed, and device registers that change
in response to outside events not known to the compiler.

>Do any of you have some practical experience, plus suggestions for
>living in the brave new ANSI-C world?

I have a "standard C language assist" file <std.h> that I configure
for each system I port to, and that I include in each source file of
my applications.  A portion of it follows:

#if __STDC__
typedef void	*pointer;		/* generic pointer */
#else
typedef char	*pointer;		/* generic pointer */
#define	const		/* nothing */	/* ANSI C type qualifier */
/* There really is no substitute for the following, but these might work: */
#define	signed		/* nothing */	/* ANSI C type specifier */
#define	volatile	/* nothing */	/* ANSI C type qualifier */
#endif

Then I simply use the appropriate type qualifiers in my code, for
example "volatile" on a "signal_was_seen" flag.  In non-ANSI C
environments the qualifiers in effect vanish and I get whatever the
compiler gives me, which MAY be what I need.  (That assumption was
implicit in your discussion.)

Really, C optimizers always have been hard to second-guess.  At least
ANSI C imposes SOME limits on the degree to which optimization can be
carried out.



More information about the Comp.lang.c mailing list