Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this function cast an int argument to a volatile pointer and immediately dereferences it?

Tags:

I just want to know what below function is doing

static int myfunc(int val) {     return *(volatile int *)val; } 
like image 416
Chinna Avatar asked Jul 02 '13 12:07

Chinna


People also ask

What is the use of volatile pointer in C?

The volatile keyword is intended to prevent the compiler from applying any optimizations on objects that can change in ways that cannot be determined by the compiler. Objects declared as volatile are omitted from optimization because their values can be changed by code outside the scope of current code at any time.

Can we have a volatile pointer in C?

Volatile is used in C programming when we need to go and read the value stored by the pointer at the address pointed by the pointer. If you need to change anything in your code that is out of compiler reach you can use this volatile keyword before the variable for which you want to change the value.

What is volatile int * p?

volatile int* p; is a pointer to an int that the compiler will treat as volatile . This means that the compiler will assume that it is possible for the variable that p is pointing at to have changed even if there is nothing in the source code to suggest that this might occur.


2 Answers

If val is a pointer when you pass it to this function, it makes sure that the value pointed by this pointer is read and returned to the caller.

I suspect this might be a trick for embedded devices, where sometimes the operation of reading a value at an address has some effect on the hardware.
For instance, reading from an hardware FIFO will pop the read value from the FIFO.

Marking here the pointer as volatile make the compiler not optimize the read if it detects that the value is not used.

Example:

#define FIFO_ADDRESS 0x800050  static int myfunc(int val) {     return *(volatile int *)val; // the address *will* be read }  static int bad( int val ) {     return *(int*)val; // might be optimized to nop()                          // by the compiler if the value                         // is not used by the caller }  int main(){    bad( FIFO_ADDRESS );    // could be NOP since return value is not used     myfunc( FIFO_ADDRESS ); // *WILL* perform a READ operation on the FIFO,                             // even though the result is not used, because                             // of the volatile keyword  } 

Note that I would do it differently, probably with a smartly named macro:

#define FORCE_INT_PTR_READ( address ) *(volatile int *)address  

Could you give us an example of usage in your case?

like image 69
Gui13 Avatar answered Oct 21 '22 10:10

Gui13


It appears to be trying to confuse the optimiser (and possibly the user). It is taking an integer, treating it as a pointer to an integer, and dereferencing it. The 'volatile' ensures that the optimiser will generate code for that dereference at that point and won't let the optimiser omit the fetch from memory. This is usually used for accessing memory mapped hardware registers,

like image 22
Tom Tanner Avatar answered Oct 21 '22 10:10

Tom Tanner