14

How to declare a pointer to function in C, in order that the pointer itself is volatile.

static void volatile (* f_pointer)(void*);

static void (volatile * f_pointer)(void*);

static void (* volatile f_pointer)(void*);

Why I asking this? I read at http://wiki.answers.com/Q/Volatile_example_code_sample_coding_of_volatile_pointer about volatile pointers.

There are sometimes problems with volatile pointers and pointer-to volatile:

Now, it turns out that pointers to volatile variables are very common. Both of these declarations declare foo to be a pointer to a volatile integer:

volatile int * foo; 
int volatile * foo; 

Volatile pointers to non-volatile variables are very rare (I think I've used them once), but I'd better go ahead and give you the syntax:

int * volatile foo;

So, I want to get a volatile pointer to function not a pointer to "volatile" function.

Thanks

osgx
  • 90,338
  • 53
  • 357
  • 513
  • 4
    Why do you want a volatile pointer to a function? Who is going to be changing this pointer? Do you know what `volatile` _really_ means? – James McNellis Feb 02 '11 at 17:44
  • @James McNellis, Yes, I want. This pointer is changed by thread 0 and used by threads 1..7 to start a function. There is a barrier between, but I want compiler to flush this pointer to memory in thread 0 before entering a barrier. Also I want threads 1..7 to re-read this pointer (there is a loop of `{ barrier, pointer read, calling function }` ). I use a system with a lot of registers available, so compiler may cache a lot of variables. Am I right? – osgx Feb 02 '11 at 18:01
  • If the barrier is written correctly, the compiler should not be caching values across it - the `volatile` should be unnecessary. – caf Feb 03 '11 at 00:44
  • 1
    @caf, glad to see you. What about a code `a=1; pthread_barrier(); b=a;` Is the pthread_barrier a wrong written one? Compiler knows nothing about insides of this function. Can the compiler cache the value of `a` around this function call (in its point of view it is usual func. call)? Compiler can cache any non-volatile variable. – osgx Feb 03 '11 at 01:15
  • 3
    In a correct pthreads implementation, `pthread_barrier_wait()` must act as a compiler barrier (which prevents values from being cached across it). In practice, specific compiler support is unnecessary, because `pthread_barrier_wait()` is an external function, so the compiler must assume that it could modify any global variable or any variable whose address has been taken (that is, from the compiler's point of view it is `pthread_barrier_wait()` that might have modified `a`, rather than another thread). – caf Feb 03 '11 at 01:20

3 Answers3

20

Think of the asterisk as a "barrier". Qualifiers (const or volatile) closer to the variable name than the asterisk modify the pointer itself. Qualifiers farther way from the variable name than the asterisk modify what the pointer will refer to. In this case, therefore, you would have:

static void * volatile f_pointer(void *);

Except, of course, that you need parens to define a pointer to a function instead of declaring a function returning a pointer:

static void (*volatile f_pointer)(void *);

static is a storage class rather than a qualifier, so the same is not true in its case. You can only specify a storage class for the variable itself, not what it points at. There's no such thing as a "pointer to extern int" or "pointer to static int", only "pointer to int". If you specify a storage class (static or extern), it always comes first.

Other threads have discussed the relationship between threading and volatile so I won't repeat that here beyond noting that this probably won't be useful.

Community
  • 1
  • 1
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
10

cdecl comes in really handy for this sort of problem:

$ cdecl
Type `help' or `?' for help
cdecl> declare f_pointer as static volatile pointer to function(pointer to void) returning void
static void (* volatile f_pointer)(void *)
cdecl>

Source of cdecl: http://cdecl.org/files/cdecl-blocks-2.5.tar.gz

osgx
  • 90,338
  • 53
  • 357
  • 513
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • @osgx, it's included with a lot of development environments. I seem to remember building mine from source, but I don't remember where I got it. You can use it online at http://cdecl.org/. – Carl Norum Feb 02 '11 at 17:49
  • Thanks! Can you name some IDE, which includes a cdecl? (I think ny IDE with cdecl included must be very user-friendly) – osgx Feb 02 '11 at 17:53
  • @osgx, sorry - I don't know of any such thing. I just use it as a command-line program. – Carl Norum Feb 02 '11 at 19:53
9
static void (* volatile f_pointer)(void*);