P99
|
◆ P99_CALL_DEFARG
Define a replacement macro for functions that can provide default arguments to the underlying real function. This macro may be used for ‘overloading’ system functions or functions that you define yourself. It is easiest to explain this with an example. The system function int pthread_mutex_init(pthread_mutex_t *mut, pthread_mutexattr_t* attr);
Here the second argument is used to specify an ‘attribute’ to the mutex The following lines heal this. #define pthread_mutex_init(...) P99_CALL_DEFARG(pthread_mutex_init, 2, __VA_ARGS__)
P99_DECLARE_DEFARG(pthread_mutex_init, , (pthread_mutexattr_t*)0);
This declares a macro If the initialization value for argument 1 is omitted (arguments count from 0) the default value of a null pointer constant is used. Valid use is static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutexattr_t attr;
.
pthread_mutex_init(&mut, &attr); // full specification with attributes
pthread_mutex_init(&mut, 0); // still a valid form
// easy variant for everyday use, equivalent to the previous one
pthread_mutex_init(&mut);
// Also function pointers can still be taken.
int (*myFunc)(pthread_mutex_t *, pthread_mutexattr_t*) = pthread_mutex_init;
This macro is more flexible than the corresponding C++ feature of default arguments. It also lets you omit middle arguments. More technically, for arguments that are omitted this just requires that NAME_defarg_M is defined for function NAME and M and that it is callable without arguments. This may just be a function (as implicitly defined by P99_DECLARE_DEFARG) or a macro. For the first case everything the function refers to must be declared at the point of its definition. For the second case, the macro is evaluated at the place of the call and could refer to local variables or anything you like. |