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

I have a portion of code along the following lines:

volatile unsigned char x ; unsigned int f(unsigned char *y) ;

When I do

unsigned int z = f(&x) ;

the compiler issues the following warning:

warning: passing arg 1 of `f' discards qualifiers from pointer target type

What does this exactly mean? How do I change my code so that the compiler is happy about it?

Reply to
James H. Newman
Loading thread data ...

x is volatile, so &x is a pointer to a volatile variable. However, the receiving function is prototyped for non-volatile and so is not going to know to preserve volatile semantics.

You could prototype f with y being volatile. Or you could create a new non-volatile variable, initialize that with x's current value, send that to f and store the modified result after f into x. However, if x happens to be a memory-mapped I/O register or the like, or happens to be set by a signal processing routine, then that probably won't give you are result you want.

--
Current spam load: 750-800 messages per day (March 4, 2008)
Reply to
Walter Roberson

On Fri, 11 Jul 2008 22:15:12 +0000 (UTC), Walter Roberson posted:

A question for you, Walter.

Since C is completely safe, why does one use the 'volatile' function specifier?

--
Temptation is a woman's weapon and man's excuse.
H. L. Mencken
Reply to
Ron Ford

I don't recall ever saying that "C is completely safe". It was certainly never designed to be "completely safe".

-- "Product of a myriad various minds and contending tongues, compact of obscure and minute association, a language has its own abundant and often recondite laws, in the habitual and summary recognition of which scholarship consists." -- Walter Pater

Reply to
Walter Roberson

On Sat, 12 Jul 2008 13:59:11 +0000 (UTC), Walter Roberson posted:

No, I was engaging in hyperbole. I think of that which is "volatile" to be opposed to that which is "safe." I've never used this qualifier in my own code.

So I spent some time with K&R, thinking I would there find the reason to use the "volatile." Instaed I find §A8.2 in the footnote: "the const and volatile properties are new with the ANSI standard. The purpose of const .... The purpose of volatile is to force an implementation to suppress optimization that could otherwise occur...."

I'm not really any closer than a half hour ago. What is the difference between type specifiers and type qualifiers?

--
Time stays, we go.
H. L. Mencken
Reply to
Ron Ford

The English meaning of the term doesn't tell you much about what it means in C. "volatile" is not the opposite of "safe" in this context.

If a program reads the value of a variable, and the compiler is able to determine what its current value happens to be, it can generate code that doesn't actually load the variable's value. For example:

... int x = 42; printf("x = %d\n", x); ...

The compiler can legitimately replace the printf() call with puts("x = 42"); because it *knows* what the result of evaluating x would have been.

If x were qualified with "volatile", it would not be permitted to perform that optimization.

The same applies to writes as well as reads.

The latest draft of the standard is at . It defines both terms, in 6.7.2 and 6.7.3, respectively.

The type specifiers are void, char, short, int, long, and so forth.

The type qualifiers are const, restrict, and volatile (restrict is new in C99).

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply to
Keith Thompson

On Mon, 14 Jul 2008 00:46:14 -0700, Keith Thompson posted:

This is a somewhat abstract point here. Can one restate this in terms of

*external* functions that might be called?

Of which type was register?

I looked at §6.7.2 and the next and am confident that this is beyond my experience.

--
I confess I enjoy democracy immensely. It is incomparably idiotic, and
hence incomparably amusing.
H. L. Mencken
Reply to
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?

[...]

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).

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply to
Keith Thompson

On Tue, 15 Jul 2008 08:31:50 -0700, Keith Thompson posted:

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.

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

--
Every election is a sort of advance auction sale of stolen goods.
H. L. Mencken
Reply to
Ron Ford

[ ... ]

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.

Reply to
santosh

On Wed, 16 Jul 2008 13:52:15 +0530, 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. 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];

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."

--
Platitude: an idea (a) that is admitted to be true by everyone, and (b)
that is not true.
H. L. Mencken
Reply to
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.)

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

Reply to
Mark L Pappin

On Thu, 17 Jul 2008 07:36:11 +1000, Mark L Pappin posted:

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?

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?

--
The basic fact about human existence is not that it is a tragedy, but that
it is a bore. It is not so much a war as an endless standing in line.
H. L. Mencken
Reply to
Ron Ford

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).

'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 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.

...

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

Reply to
Mark L Pappin

On Fri, 18 Jul 2008 12:33:56 +1000, Mark L Pappin posted:

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,

--
To die for an idea; it is unquestionably noble. But how much nobler it
would be if men died for ideas that were true!
H. L. Mencken
Reply to
Ron Ford

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.