简体   繁体   中英

Cast a long to a function pointer?

I have the following code:

long fp = ...
void (*ptr)(long, char*, char*) = fp;

The long fp is a correct function pointer, which comes in as a long. I am getting the standard "makes pointer from int without a cast" warning. I want to be able to compile with:

-std=iso9899:1990 -pedantic-errors

which turns that warning into an error. The question is: what is the correct cast? I have tried various guesses, eg:

void (*ptr)(long, char*, char*) = (void)(*)(long, char*, char*) fp;

But can't seem to find the right one.

The "correct" cast is:

void (*ptr)(long, char*, char*) = (void (*)(long, char*, char*))fp;

Obviously, this can be tidied up with a suitable typedef.

But either way, the result of this is implementation-defined. If you can, avoid this, and maintain the pointer in a pointer type. Next best thing would be to use intptr_t if it's available.

Probably it's something like:

void (* ptr)(long, char, char *) = (void (*)(long, char, char *))fp;

but my suggestion is to use a typedef and forget about all this mess:

typedef void (* fnPtr)(long, char, char*);
fnPtr ptr = (fnPtr) fp;

The only "correct" way is not to cast at all, but rather copy the binary representation:

long fp;
void (*ptr)(long, char*, char*);

memcpy(&ptr, &fp, sizeof ptr);

The main problem here is, that ANSI-C does not allow this, despite the countless C-APIs out there relying on this feature. Therefore, you will likely run into trouble when compiling with -pedantic . As was hinted by other posters, you can cheat around the cast by using things like memcpy() or a union type for casting.

By the way, POSIX guarantees that this will work, so the part about 'implementation-defined results' gets a lot less scary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM