Reputation: 9743
I am using scandir to match certain files from a dir. The match function takes const struct dirent *dp
argument.
But I also need to pass another argument with it. When I try to do that, compiles gives me a warning (not error) that my match function is of incompatible pointer type.
Is it not allowed to pass another argument to match function? If it's not, I might have to make that particular variable global which I do not want to do.
code snippet:
/* below I am adding new argument - char *str */
match_function (const struct dirent *dp, char *str) {
}
function() {
count = scandir(PATH, &namelist, match_function, alphasort);
}
warning:
warning: passing argument 3 of 'scandir' from incompatible pointer type
Upvotes: 2
Views: 2838
Reputation: 825
To explicitly answer your question
Is it not allowed to pass another argument to match function?
No. The author of scandir()
specified what type of match
function it expects; as the user of scandir()
you must follow that specification, or write your own scandir()
-equivalent that does things the way you want as suggested by R...
Upvotes: 2
Reputation: 215567
Another approach, which may be preferable to using global variables or thread-specific data, is just to write your own replacement for scandir
and have it take an extra void *
argument which it would pass to the match function. Considering that scandir
is easily implemented in less than 50 lines of code, this is perfectly reasonable.
Here is a possible implementation of scandir
:
http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=src/dirent/scandir.c
Upvotes: 2
Reputation: 215567
The only portable and thread/library-safe way to do what you want is with POSIX thread-specific data.
static pthread_key_t key;
static pthread_once_t init = PTHREAD_ONCE_INIT;
static void initfunc()
{
int r = pthread_key_create(&key);
assert(r==0);
}
match_function (const struct dirent *dp)
{
char *str = pthread_getspecific(key);
/* ... */
}
function() {
pthread_once(&init, initfunc);
pthread_setspecific(key, str);
count = scandir(PATH, &namelist, match_function, alphasort);
}
If you don't care about thread-safety you can just use a global variable for str
and make it a lot easier.
Upvotes: 2
Reputation: 61457
Think about it: how would you pass the additional parameter to it? What you're probably looking for is a closure, which isn't supported by the C standard yet although gcc
apparently has the ability to do it via nested functions.
Upvotes: 0