0

Some C library function omit warnings via the compiler when volatile values are passed to them; for example memcpy(). Now I wondered whether I could use some volatile casts to enforce immediate evaluation. Consider:

int b; /* ... */
(volatile int) b = 1;
b = (volatile int) 1;

Now does the second line cause immediate assignment to b, and does the third line do the same? Or can't a constant like 1 be made "more volatile" (meaning it won't have any effect)?

Lundin
  • 195,001
  • 40
  • 254
  • 396
U. Windl
  • 3,480
  • 26
  • 54
  • 1
    `(volatile int) b = 1` creates a temporary, an rvalue. You can't assign to that. Perhaps `*((volatile int*)&b) = 1;` would make a difference. You'd better check the assembly. – Ted Lyngmo Dec 16 '21 at 13:41
  • Immediate as in what, an immediate assembler instruction or just English "immediately"? – Lundin Dec 16 '21 at 13:42
  • @TedLyngmo Yes, I cannot assign to that, but the expression will yield a "volatile" value that's being ignored. But the side-effect should be that the instruction is not moved around by the compiler, I guessed. – U. Windl Dec 16 '21 at 13:45
  • @Lundin Just imagine there are many other instruction before and after that statement (as suggested by `/* ... */`). Immediate should mean that the compiler does not move the statement around, meaning it's evaluated *after* the instructions before were executed, and the instructions after that are executed - well - after that statement. – U. Windl Dec 16 '21 at 13:48
  • "_but the expression will yield a "volatile" value_" - I don't see it since it will not compile. – Ted Lyngmo Dec 16 '21 at 13:48
  • Hmm. I had a `if ((volatile int) b == 0) ...` that compiled with gcc-4.8.5. So I assumed `(volatile int) b` would be a valid expression, too. Sorry that I had mis-typed `volatile` in my question. OK, I might have mixed *reading* and *writing*... – U. Windl Dec 16 '21 at 13:51
  • @U.Windl It's complicated. If reading the (unhelpfully vague) C standard strictly, `volatile` should act as a memory barrier. In practical implementations, it does not always do that. See https://stackoverflow.com/a/53416572/584518 – Lundin Dec 16 '21 at 13:53
  • Also... fun fun, while writing an answer I think I just found a bug in gcc 11. – Lundin Dec 16 '21 at 14:04
  • 1
    For those interested I posted a question about the bug here: [Non-conforming optimizations of volatile in gcc 11.1](https://stackoverflow.com/questions/70380510/non-conforming-optimizations-of-volatile-in-gcc-11-1) – Lundin Dec 16 '21 at 14:17

1 Answers1

1

Qualifiers (const, restrict, volatile, and _Atomic) never apply to values. They only apply to objects, because they tell the compiler something about how to handle the memory of an object.

So (volatile int) b and (volatile int) 1 have no effect different from (int) b and (int) 1.

You can access a non-volatile object with a volatile lvalue, as with * (volatile int *) &x = value;. Then the C implementation must access the object (read or write it) strictly according to the semantics of C’s abstract machine. It may be reordered with other non-volatile expressions generally but not with observable behaviors: accessing volatile objects, interactive I/O, and writing to files.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312