tags:

views:

89

answers:

4

The code states:

void (* log_msg)(char *msg)
    =printf;

void change_and_log(int *buffer, int offset, int value){
    buffer[offset] = value;
    log_msg("changed");
}

I'm most concerned with the first part:

Firstly, what does the signature void (* log_msg)(char *msg) mean? Is this code simply mapping the function log_msg to printf? In that case, why is the function name (* log_msg) and not simply log_msg?

+2  A: 

The top two lines are establishing a function pointer (hence the *), the function is named log_msg, and it's then set to point to printf - after which a call to log_msg ends up calling printf.

Will A
You can do that?! wahoo...
piggles
Just because you can doesn't mean you should. ;)
Will A
+6  A: 

void (* log_msg)(char *msg) is actually a function pointer. You could view this as

typedef void (*LoggerFunctionPointer)(char* msg);

LoggerFunctionPointer log_msg = printf;

Yes, it maps log_msg to printf, but no, log_msg isn't a function, but a pointer that points to a function printf.

Using a function pointer has the advantage that the log_msg can be switched at runtime. For example, you could provide a switch in the interface that

void no_log_msg(char* msg) {}
...
if (enable_debug) {
  log_msg = printf;
} else {
  log_msg = no_log_msg;
}

then, without changing other source code, all logging can be inhibited.


(BTW, the sample code is incorrect because the signature of printf is int printf(const char*, ...). To avoid the implicit cast, log_msg should be declared as

int (*log_msg)(const char*, ...) = printf;

)

KennyTM
Exactly. The "academic paper" made a rather serious error. You can't call `printf` as an `void (char *)` function. Basically, every single type in the pointer declaration is wrong.
AndreyT
+2  A: 

It's a function pointer.

The type of a function pointer is R (*)(Args...), where R and Args... are replaced with the return type and arguments, if any. It is read as "a pointer to a function that takes arguments Args... and returns R."

Your code would read easier as:

// print_function is a type that is a function pointer
typedef void (*print_function)(char *msg); 

// log_msg is a variable of the type print_function: it points to a function
print_function log_msg = printf; // point to printf

And later, it's just calling that function via a function pointer.

GMan
Please switch the accepted answer to KennyTM's, it's more correct.
GMan
+2  A: 

log_msg is a function pointer, in particular a "pointer to a function taking a char * and returning void". In this case it's just used as an alias for printf (but could point to any function with the same arguments and return type).

The syntax for function pointers in C can be pretty intimidating at first.

isbadawi