What is the meaning of this warning, and how do I get rid of it?

K

Keith Thompson

Ron Ford said:
This is a somewhat abstract point here. Can one restate this in terms of
*external* functions that might be called?

Not usefully. What makes you think that external functions would make
this clearer, or that "volatile" and external functions are related to
each other?

[...]
Of which type was register?

Neither. "register" is a storage-class specifier, as are typedef,
extern, static, and auto (C99 6.7.1). ("typedef" is treated as a
storage-class specifier only for syntactic convenience; it doesn't
actually specify a storage class.)

A type specifier specifies what type you're using (int vs. double,
etc.).

A type qualifier gives you additional information about a type,
usually something that applies to a specific object (it can't be
modified, for example).

A storage-class specifier (other than typedef) specifies the storage
class of a declared entity (its lifetime and, in an abstract sense,
where it's stored).
 
K

Keith Thompson

Ron Ford said:
The fact that I have to ask leaves me to believe that I have no use
for the 'volatile' function qualifier. I had hoped that things I
didn't know about 'volatile' would enlighten things I didn't know
about the function specifier 'fortran', but not so.

What is a "function qualifier"? "volatile" is a *type qualifier*.
It's typically applied to objects, not to functions.

You *could* declare something like:

volatile int func(void) { ... }

but it wouldn't make sense; the "volatile" would just be ignored.

Or you could declare:

volatile int *another_func(void) { ... }

but that means that another_func returns a pointer to volatile int; it
applies to the object that the result points to, not to the function.

I think that much of your confusion stems from your incorrect
assumption that "volatile" is for functions.

As for "fortran", that's a non-standard extension. It's listed under
"Common extensions" in C99 J.5, but I haven't actually seen a compiler
that supports it. Here's what the standard says about it:

The fortran function specifier may be used in a function
declaration to indicate that calls suitable for FORTRAN should be
generated, or that a different representation for the external
name is to be generated (6.7.4).

But this is in a non-normative section of the standard.

If you want to know about a non-standard "fortran" keyword, you'll
have to consult the documentation of whatever compiler supports it --
and be aware that it's not at all portable.

(The only standard function specifier (not "function qualifier") is
"inline".)
 
R

Ron Ford

Not usefully. What makes you think that external functions would make
this clearer, or that "volatile" and external functions are related to
each other?

Well I clearly had notions about volatile that were compleatly wrong. I'm
just going to leave it at as "ensuring that code not be optimized away,"
and think of the above source as illustrative.

Neither. "register" is a storage-class specifier, as are typedef,
extern, static, and auto (C99 6.7.1). ("typedef" is treated as a
storage-class specifier only for syntactic convenience; it doesn't
actually specify a storage class.)

A type specifier specifies what type you're using (int vs. double,
etc.).

A type qualifier gives you additional information about a type,
usually something that applies to a specific object (it can't be
modified, for example).

A storage-class specifier (other than typedef) specifies the storage
class of a declared entity (its lifetime and, in an abstract sense,
where it's stored).

That's a lot to keep straight. I wish there was a book on reading the C
standard.
 
R

Ron Ford

I think you need to restate your question (printf and puts are
external functions). What is it about Keith Thompson's example that
needs restating?

I thought that volatile would have properties like static, but not so. I
don't seem to be running out of misconceptions on this one, so I'll commit
the above example to memory and be done with it.
 
L

lawrence.jones

Keith Thompson said:
As for "fortran", that's a non-standard extension. It's listed under
"Common extensions" in C99 J.5, but I haven't actually seen a compiler
that supports it.

I have. It meant essentially the same thing as Microsoft's "__stdcall"
does (use the system's standard calling conventions and don't mess with
the function's name), so it was widely used on systems where the
standard calling conventions don't mesh well with C. Why Microsoft
didn't just use it instead of inventing their own name, only they know.
 
K

Keith Thompson

Ron Ford said:
Well I clearly had notions about volatile that were compleatly
wrong. I'm just going to leave it at as "ensuring that code not be
optimized away," and think of the above source as illustrative.
[...]

Specifically, volatile inhibits optimizations *related to accessing an
object* (where "accessing" can be either reading or writing). Other
optimizations are generally not affected, except perhaps indirectly.
 
S

santosh

J

Joachim Schmitz

santosh said:
Ron said:
[ ... ] I wish there was a book on reading the C standard.
[ ... ]

There are two that I know of. One is the Rationale document for the
current standard published on WG14's website, the other is a *huge*
but interesting book called /The C Standard: An Economic and Social
Commentary/ by Derek Jones, again published by the author on his
website.

I won't call a 10 MB pdf file huge. Hmm, hold on: that's 1615 pages! So yes,
it is huge ...

Thanks for these usefull URLs!

Bye, Jojo
 
S

santosh

Joachim said:
santosh said:
Ron said:
[ ... ] I wish there was a book on reading the C standard.
[ ... ]

There are two that I know of. One is the Rationale document for the
current standard published on WG14's website, the other is a *huge*
but interesting book called /The C Standard: An Economic and Social
Commentary/ by Derek Jones, again published by the author on his
website.

I won't call a 10 MB pdf file huge. Hmm, hold on: that's 1615 pages!
So yes, it is huge ...

Thanks for these usefull URLs!

And of course the latest edition of Harbison & Steele's /C: A Reference
Manual/ is also a very good companion in interpreting and understanding
the Standard itself.
 
R

Ron Ford

Ron said:
[ ... ] I wish there was a book on reading the C standard.
[ ... ]

There are two that I know of. One is the Rationale document for the
current standard published on WG14's website, the other is a *huge* but
interesting book called /The C Standard: An Economic and Social
Commentary/ by Derek Jones, again published by the author on his
website.

<http://www.knosof.co.uk/cbook/cbook.html>
<http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf>

Thanks santosh, I've started picking at the Rationale document. It doesn't
take long to bump into something with the volatile type qualifier:

Such behavior is, of course, too loose for hardware-oriented applications
such as device drivers
and memory-mapped I/O. The following loop looks almost identical to the
previous example,
but the specification of volatile ensures that each assignment to *ttyport
takes place in 20
the same sequence, and with the same values, as the abstract machine would
have done.
volatile short *ttyport;
/* ... */
for (i = 0; i < N; ++i)
*ttyport = a;

I know what a device driver is but not memory-mapped IO. Here, the
rationale for volatile sounds different: "ensuring that each assignment ...
takes place in the same sequence."
 
M

Mark L Pappin

Ron Ford said:
santosh posted:
Thanks santosh, I've started picking at the Rationale document. It
doesn't take long to bump into something with the volatile type
qualifier:
Such behavior is, of course, too loose for hardware-oriented
applications such as device drivers and memory-mapped I/O.

(Not a criticism, just emphasizing a point that's been made to several
posters here recently: making some sort of visual distinction in your
post between text you have written and text you have quoted (and
citing your sources) will ease the cognitive load for your readers.
It's best to assume Usenet readers don't see font or color changes, so
conventions involving extra blank lines and attribution marking have
developed over the last few decades to help here.)
I know what a device driver is but not memory-mapped IO.

Some machines have special instructions for accessing I/O devices
(e.g. the x86 family), and I/O operations using these are not
"memory-mapped".

Some machines reserve memory addresses such that reads from or writes
to those addresses do not access actual memory, but instead read or
modify the state of other hardware.

This "memory-mapping" of I/O may be defined into the architecture
(e.g. the Microchip PIC series of microcontrollers, with I/O devices
on the chip) or it may be completely independent of the processor
(e.g. the Apple ][ family, with logic on the motherboard or expansion
cards decoding the address lines and tweaking hardware as appropriate
- any access to a specific location toggled the speaker cone, for
instance). Even machines with special I/O instructions may also have
some memory-mapped I/O.

Where 'volatile' comes in handy is in ensuring that the compiler does
not "helpfully" eliminate a read from such a memory location because
it knows what was last read from that location, or eliminate a write
because another write happens a little later and would "overwrite" any
previously-stored value. If, say, there's really a temperature sensor
feeding an ADC behind a "memory" address and a DAC driving a motor
controller behind another, then your program probably won't do as you
intended if it forever sees the temperature as being the same as when
it first read it; and only writing the final-ever requested speed to
your motor controller, at the end of the run, won't make the robot go.

mlp
 
R

Ron Ford

(Not a criticism, just emphasizing a point that's been made to several
posters here recently: making some sort of visual distinction in your
post between text you have written and text you have quoted (and
citing your sources) will ease the cognitive load for your readers.
It's best to assume Usenet readers don't see font or color changes, so
conventions involving extra blank lines and attribution marking have
developed over the last few decades to help here.)

Thanks for mentioning this. My quote was from §6.7 of the Rationale doc,
as is the quote that follows. I thought I was doing well to render it as I
did, but quotes from a .pdf doc using the text selection tool appear to
need a good deal of processing, needing a complete overhaul of newlines and
adiosing the numbers as multiples of five that serve as line numbers in the
pdf doc.

With dialog, I can paste as a quote using > or a custom quote. How does
this look:

%% A static volatile object is an appropriate model for a memory
%% -mapped I/O register. Implementors of C translators should
%% take into account relevant hardware details on the target systems
%% when implementing accesses to volatile objects. For instance,
%% the hardware logic of a system may require that a two-byte
%% memory-mapped register not be accessed with byte operations;
%% and a compiler for such a system would have to assure that no
%% such instructions were generated, even if the source code only
%% accesses one byte of the register. Whether read-modify-write
%% instructions can be used on such device registers must also be
%% considered. Whatever decisions are adopted on such issues must
%% be documented, as volatile access is implementation-defined. A
%% volatile object is also an appropriate model for a variable
%% shared among multiple processes. --§6.7

If the register is to hold the temperature in the hallway next to my
woodburner, what do "static" and "volatile" do together?
I know what a device driver is but not memory-mapped IO.

Some machines have special instructions for accessing I/O devices
(e.g. the x86 family), and I/O operations using these are not
"memory-mapped".

Some machines reserve memory addresses such that reads from or writes
to those addresses do not access actual memory, but instead read or
modify the state of other hardware.

This "memory-mapping" of I/O may be defined into the architecture
(e.g. the Microchip PIC series of microcontrollers, with I/O devices
on the chip) or it may be completely independent of the processor
(e.g. the Apple ][ family, with logic on the motherboard or expansion
cards decoding the address lines and tweaking hardware as appropriate
- any access to a specific location toggled the speaker cone, for
instance). Even machines with special I/O instructions may also have
some memory-mapped I/O.

Where 'volatile' comes in handy is in ensuring that the compiler does
not "helpfully" eliminate a read from such a memory location because
it knows what was last read from that location, or eliminate a write
because another write happens a little later and would "overwrite" any
previously-stored value. If, say, there's really a temperature sensor
feeding an ADC behind a "memory" address and a DAC driving a motor
controller behind another, then your program probably won't do as you
intended if it forever sees the temperature as being the same as when
it first read it; and only writing the final-ever requested speed to
your motor controller, at the end of the run, won't make the robot go.

Thanks mlp. I have this fantasy of being able to teach my x86 computer to
fire events based on temperature. The calculus is very simple and involves
two fans and a swamp cooler. One of the fans is next to the woodburner,
and the swamper has 2 switches: one for the motor and one for the pump.
(If you haven't lived somewhere near Albuqerque, you probably have never
experienced evaporitive cooling.)

I'm mudding all the walls, so burying wires to wherever they need to be is
in the cards. Do you have any notion of what hardware/software I would
need to make that a reality?
 
M

Mark L Pappin

With dialog, I can paste as a quote using > or a custom quote. How does
this look:

%% A static volatile object is an appropriate model for a memory
%% -mapped I/O register. Implementors of C translators should
%% take into account relevant hardware details on the target systems
%% when implementing accesses to volatile objects.

Looks fine to me, and makes it obvious that the quote has come from
somewhere other than Usenet. There are also arguments for sticking
with '>' (providing you keep attributions/citations clear).
If the register is to hold the temperature in the hallway next to my
woodburner, what do "static" and "volatile" do together?

'static' at file scope (and in practice such memory-mapped I/O would
usually be represented by file-scope objects only) affects visibility
only.

A compiler might use 'static volatile' on definitions for variables
representing memory-mapped registers in a non-standard header (along
with some other magic to tie those "variables" to specific addresses),
where the 'static' stops the compiler's parser complaining about
duplicate definitions if the header is pulled in in multiple places
(since all the "definitions" actually refer to the same thing, and the
back end doesn't end up actually allocating space anyway).

You'd probably not explicitly use 'volatile' yourself, but have
something like

#include <compiler's-magic-chip-specific-header>
/* At this point, a number of objects have been declared
that refer to the memory-mapped I/O ports. They probably
have names full of acronyms from data sheets. They also
have been declared with whatever qualifiers are necessary. */

#define HALLWAY_TEMP ADC_DATA_IN_0
#define BEDROOM_TEMP ADC_DATA_IN_1
#define WATER_LEVEL ADC_DATA_IN_2

#define SWAMPCOOLER_FAN DAC_DATA_OUT_0
#define REFILL_SOLENOID RELAY_OUT_0

/* hard-coded parameters for simplicity of sample */
#define HALLWAY_MAX 35
#define BEDROOM_MAX 30

#define FANSPEED_MAX 100

#define LO_WATER 10
#define HI_WATER 40

int main(void)
{
unsigned fanspeed = 0;
while (1) {
if (HALLWAY_TEMP > HALLWAY_MAX ||
BEDROOM_TEMP > BEDROOM_MAX) {
if (fanspeed < FANSPEED_MAX) {
/* some output devices are truly output-only
and it's necessary to keep your own record
of their value, rather than accessing them
_just_ like a real variable */
SWAMPCOOLER_FAN = ++fanspeed;
}
}
if (HALLWAY_TEMP < HALLWAY_MAX &&
BEDROOM_TEMP < BEDROOM_MAX) {
if (fanspeed > 0) {
SWAMPCOOLER_FAN = --fanspeed;
}
}
if (WATER_LEVEL < LO_WATER) {
REFILL_SOLENOID = 1;
}
if (WATER_LEVEL > HI_WATER) {
REFILL_SOLENOID = 0;
}
}
return 0; /* for pedantry's sake */
}

Real code would initialize devices; this sample doesn't. Real code
would also probably need to worry about triggering ADC conversions and
waiting until results were ready before reading the converted value,
and also mapping such values onto some temperature scale that reads
other than 0..1023. Devices other than ADCs would have their own
real-world issues too.
Thanks mlp. I have this fantasy of being able to teach my x86
computer to fire events based on temperature. ....
(If you haven't lived somewhere near Albuqerque, you probably have
never experienced evaporitive cooling.)

Grew up in tropical North Queensland - experienced it plenty,
occasionally even via artificial means. And some Aussies have canvas
waterbags strapped to the front of their 4WDs (you'd call them SUVs)
for cold water in hot weather - same principle.
I'm mudding all the walls, so burying wires to wherever they need to
be is in the cards. Do you have any notion of what
hardware/software I would need to make that a reality?

I do, but discussing it is not appropriate here in comp.lang.c. Talk
to the good folks in comp.arch.embedded for further pointers, or email
me privately for consulting.

mlp
 
C

CBFalconer

Mark said:
Looks fine to me, and makes it obvious that the quote has come
from somewhere other than Usenet. There are also arguments for
sticking with '>' (providing you keep attributions/citations
clear).

Actually the arguments against using anything other that '>' are
overwhelming. The point is that most software can recognize the
'>' marker and take appropriate action while reformatting
over-length lines, etc. Odds are greatly against success with any
other marker.

There are similar arguments agains indenting either your quotes or
your additions. The problems don't show up immediately, but do
appear after further requoting. I use indenting for actual
quotation from third parties, i.e. non-usenet messages, and
normally enclose such quotes in quote marks. E.g.:

"This is a third party
quotation. Note the
terminal quote mark.
Also note the revision
of the subject header."
 
R

Ron Ford

Grew up in tropical North Queensland - experienced it plenty,
occasionally even via artificial means. And some Aussies have canvas
waterbags strapped to the front of their 4WDs (you'd call them SUVs)
for cold water in hot weather - same principle.


I do, but discussing it is not appropriate here in comp.lang.c. Talk
to the good folks in comp.arch.embedded for further pointers, or email
me privately for consulting.

mlp

I don't know how to set the follow-up with this client. I'll download MS's
latest C product and fire up your suggestion.

Cordially,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top