Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
462 views
in Technique[技术] by (71.8m points)

C cast void pointer to function pointer

I am trying to create some macros that I can use to create my own unit testing library. My header file looks like this:

#ifndef _TEST_H_
#define _TEST_H_

#include <stdio.h>
#include "hehe_stack.h"

static hehe_stack* tests;
typedef int (*testfunc)();

#define test_init() tests = hehe_stack_init();
#define test_register(test) hehe_stack_push(tests, test);
#define test_info() fprintf(stdout, "running %s :: %s 
", __FILE__, __func__);
#define test_run() testfunc = (int (*)()) hehe_stack_pop(tests); testfunc(); return 0;

#endif

In each test .c file I want to push a number of function pointers into the tests stack and then pop each function pointer out of the stack and call it. My stack pop method returns a void pointer, and the function pointer that I am pushing onto it returns an int and takes no parameters. Is my syntax incorrect? I feel like I should be able to do this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The C99 standard does not allow to convert between pointers to data (in the standard, “objects or incomplete types” e.g. char* or void*) and pointers to functions.

6.3.2.3:8 A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined.

One reason is that pointers to objects and pointers to functions do not have to be the same size. On an example architecture, the former can be 64-bit and the latter 32-bit.

You can cast from a pointer to a certain function type to a pointer to another function type, and this is the technique I recommend you use if you need to store function pointers in a data structure. Any function type will do. This means you cannot reuse a data structure intended for data pointers. You need to duplicate the data structure and change it to hold function pointers.

Do not forget to cast back to the proper function pointer type before calling, otherwise this is undefined behavior.

NOTE that, as pointed out by Andrew Mellinger, some compilers allow the conversion in each direction. C11's annex “J.5 Common extensions” lists:

J.5.7 Function pointer casts

1 A pointer to an object or to void may be cast to a pointer to a function, allowing data to be invoked as a function (6.5.4).

2 A pointer to a function may be cast to a pointer to an object or to void, allowing a function to be inspected or modified (for example, by a debugger) (6.5.4).

Some POSIX interfaces, such as dlsym(), also in effect mandate these conversions to be valid in the POSIX system's C compiler.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...