How do I approach a function echo_tpl that can take 1 parameter of type int or string ,and print it out?
C doesn't have templates. I think the best you could do is to use an union or to have the functions have different names. The latter way of having different names is the quasi-standard method of doing it (for instance fabs fabsf fabsl, also heavily used by OpenGL which also accounts for the fact C can't overload functions)
void echo_tpl_s(char const *string) { /* ... */ }
void echo_tpl_i(int number) { /* ... */ }
int main(void) {
echo_tpl_s("Hello world");
echo_tpl_i(42);
}
If there is a lot of common code, you may decide to factor it out in separate functions
void echo_tpl_s(char const *string) {
prepare_output_device();
printf("%s", string);
unprepare_output_device();
}
void echo_tpl_i(int number) {
prepare_output_device();
printf("%d", number);
unprepare_output_device();
}
Or you can take the union way, which will have the function names be equal but instead blow up the parameter type with meta informations.
enum Type {
Number,
String
};
struct Value {
enum Type type;
union {
int number;
char const *string;
} u;
};
void echo_tpl(struct Value value) {
switch(value.type) {
case Number: printf("%d", value.u.number); break;
case String: printf("%s", value.u.string); break;
}
}
int main(void) {
echo_tpl((struct Value) {
.type = String,
.u.string = "Hello world"
});
}
The union way is particular well-suited if you want to store the value somewhere and then execute the print function without caring what value type you pass to it. In C89 you would need to create the value separately since it doesn't have compound literals
int main(void) {
struct Value value;
value.type = String;
value.u.string = "Hello world";
echo_tpl(value);
}
It's a good idea to create functions for that, though
struct Value stringval(char const *string) {
struct Value value;
value.type = String;
value.u.string = string;
return value;
}
struct Value numberval(int number) {
struct Value value;
value.type = Number;
value.u.number = number;
return value;
}
int main(void) {
echo_tpl(stringval("Hello world!"));
}
Some compilers may provide extensions for writing such things. For instance Clang provides function overloading in C.
void echo_tpl(int value) __attribute__((overloadable)) {
printf("%d", value);
}
void echo_tpl(char const *value) __attribute__((overloadable)) {
printf("%s", value);
}
This solves the call-side of the function not to depend on the type. On the definition side, you still have to write the code twice. That's mainly because (as another answer explains) C doesn't have type-generic output functions. Of course if you use this feature, your code becomes nonportable.
The traditional way to translate templates to C is using the preprocessor. I'd do it something like this:
// this creates each template "instance"
#define ECHO_TPL_IMPLEMENT(t) void echo_tpl_##t(t param){\
/* this is where you write your function that uses param */ \
}
// this calls the specific template instance
#define ECHO_TPL(t, val) echo_tpl_##t(val)
// as i wrote it, the function only accepts a 1 word parameter type
// so for simplicity, i'm defining char* to be string
typedef char *string;
// i implement the function for the types int and string
ECHO_TPL_IMPLEMENT(int) // creates echo_tpl_int
ECHO_TPL_IMPLEMENT(string) // creates echo_tpl_string
main()
{
// then i just call them and let the preprocessor handle it
ECHO_TPL(string, "meep"); // will call echo_tpl_string
ECHO_TPL(int, 10); // will call echo_tpl_int
}
This is how the original C++ compilers handled templates, only they had (and still do to this day) more complex type mangling rules, where I just assumed types are 1 word and if they aren't, you'll have to typedef them.
edit: Note that I left the function empty. This is indeed how you write "templated functions" in C, but I cant really write the parameter like you asked because C doesn't have a type-independent file writing api. printf and write require information about the actual type (through the %d or %s and through the length in bytes of what to write respectively), and we don't have that.
Also note that this applies to C++ too. You can't use the C api to write to a file from a template either, you can only really use cout (or the boost format alternative or something similar). You'll have to think what you want to do with the actual function.
Late, but worth adding to this that as of the C11 standard, C now has some very limited support for overloading by using _Generic expressions, that select the right result expression at compile-time based on the type of an input. Nothing like templates but they can answer this old question like this:
#define echo_tpl(X) _Generic((X), int: echo_tpl_i, \
char *: echo_tpl_s)(X)
void echo_tpl_s(char const *string) { /* ... */ }
void echo_tpl_i(int number) { /* ... */ }
int main(void) {
echo_tpl("Hello world");
echo_tpl(42);
}
You still have to define the function implementations using separate names as you would in C99, but you can define a macro with the C++-ish name that inserts a _Generic expression at every point of use, in order to choose the right version for that call site, without making the function user think about the argument type.
It seemingly takes forever for C standards to be fully adopted and I have no idea which compilers implement this feature, but it will become widespread sooner if more people go forth and use it!
template <typename T>
void echo_tpl(const T& t) { std::cout << t; }
EDIT: I didn't spot the c tag. The above answer only works with C++.
Related
i have to use same function for different data types to avoid extra functions and lengthy code.
i am taking (void*) argument in function and want to retrieve back the same datatype that i have sent from main. i.e if int comes from main, i should be able to guess the int datatype from void* of "func". here's sample function...
void func(void* input)
{
if(input is int)
printf("%d", input);
else if (input is char)
printf("%c", input);
else if (input is struct)
//do somthing;
}
and the main is:
int main()
{
int q=1;
char w='c';
func(&q);
func(&w);
func(&struct);
return 0;
}
When a function argument is declared as a void * then any type information is not available to the function. C does not provide a way to inspect a void * variable to determine it real type.
This means that when a function such as you describe with a void * argument is being used with multiple types then the argument must include some kind of annotation or indication as to the type.
One standard way is to use a struct which contains a type indicator followed by a union of all the various types supported.
typedef struct {
unsigned short usType;
union {
int iValue;
float fValue;
} U;
} MyVoidType;
Another way is to use a void * argument for the thing to be processed by the function with a second argument indicating the type.
func(void *pItem, unsigned short usType)
{
switch (usType) {
case 1:
{
ItemType1 *pItem1 = pItem;
// do things with pItem1
}
break;
// other cases for other types
}
}
This is similar to the problems that can be experienced when using the varargs variable arguments functionality. With varargs the compile knows there are additional arguments however their type is not checked because the type information for the other arguments are not part of the function definition/declaration. The printf() family of output functions provides a work around to this with the format specifiers which the functions use to determine the type of an argument and from that how to format the value to print the argument.
There are problems with this approach because there is a need to maintain the annotation or indication with the actual data item and to make sure that any new types are supported with the appropriate changes in switch statements. It also ends up causing a problem with the compile now being unable to do argument checking for you.
So what I have also done is something like the following. In a file I have a single function that handles all the various types I want to handle. This function is then wrapped in multiple versions with the appropriate typed arguments which do nothing more than call the single function with the proper annotation.
static short funcmain(void *pItem, unsigned short usType)
{
switch (usType) {
case 1:
{
ItemType1 *pItem1 = pItem;
// do things with pItem1
}
break;
// other case statements
}
}
short funcType1 (ItemType1 *pItem)
{
return funcmain (pItem, 1);
}
short funcType2 (ItemType2 *pItem)
{
return funcmain (pItem, 2);
}
Lets say I am maintaining an array of function structures in which I store API information.
This is definition of function structure:
typedef struct function {
void (*func)(long, ...);
char* name;
int argc;
char *argv[];
} function;
function api_list[N]
I would maintain a list of such structures.
Now given any function, I want to write a function Register(api_list, fp)
which adds one such structure initialized with details of function fp.
int fp(int a, int b) {
return a+b;
}
Register(api_list, fp);
How to do it in C?
I believe you will need to either parse the C function declarations yourself or find some other code to do it. I looked around a bit and there's code for this in the Ruby FFI, PerlXS and other script binding generators like SWIG. I also saw the XML plugin to GCC which generates XML describing the program.
If you look up C's BNF or EBNF definitions and know a bit of parsing theory, figuring out C functions is not hard. C++ is a whole other ball o' wax.
Note: I think I misunderstood. The following is for calling C functions with unknown number and types of arguments. Not for finding out what the function signature already looks like.
Look at the FFI (Foreign Function Interface) library which can be found at Sourceware:
https://sourceware.org/libffi/
This is packaged with many Linux systems already because it is heavily used by interpreted languages that need to call C functions.
Now given any function, I want to write a function Register(api_list, fp) which adds one such structure initialized with details of function fp.
There is no way to do this in Standard C. The main reason is you need keep track of original definition of an function to call it via such structure. You actually could store every function pointer as struct member:
void (*func)()
that is fine, but any attempt to call such function when type is not compatible (both parameters and return type are not the same) with original definition will invoke undefined behaviour. This means, that you would need to cast it properly for every call:
((int (*)(int, int)) api_list[0])(1, 2);
You may use GCC extensions typeof, but this method requires writing function's name (here fp) explicitely:
int result = ( (typeof(fp)*) api_list[0].func)(1, 2);
Even if you have stored somehow character string "fp" inside name member, there is no way to "connect" it with typeof, since it does not take string literals (well it takes, but not in the way you want) and in general there is no way to have it "destringized" as fp token.
Here is an illustration of above concepts:
#include <stdio.h>
typedef void (*GENERIC_FUNC_PTR)();
typedef struct function
{
GENERIC_FUNC_PTR func;
} function;
void Register(function *api_list, GENERIC_FUNC_PTR func)
{
api_list->func = func;
}
int add(int a, int b)
{
return a + b;
}
void print_message(void)
{
printf("%s\n", __func__);
}
int main(void)
{
function api_list[10];
Register(api_list, (GENERIC_FUNC_PTR) add);
Register(api_list + 1, (GENERIC_FUNC_PTR) print_message);
printf("%d\n", ( (typeof(add)*) api_list[0].func)(1, 2));
( (typeof(print_message)*) api_list[1].func)();
return 0;
}
Is it possible in C(not C++) to have a fuction pointer that takes a generic value(not a pointer), with -pedantic and -wall -werror flags set.
Note: I can't change the parameter Type. The code has to support uint8_t, uint16_t, etc... types as the parameters
Goal: to solve the problem with code.
Question
Is there a way to typecast a uint8_t(and/or uint16_t) parameter to a void*(Approach1)?
specifically to pass a non-pointer type value to a void* value.
Is there a way to setup a Generic Type that will work with all the different values(Approach 2)?
Last resort
Is there a way to set a specific compiler Exception in the code?(this question has been answer)
Approach 1(causes a invalid conversion from uint8_t to void*)
typedef struct
{
void (*set_func)(void*);
} SetFunction;
void setValue(uint8_t byteValue)//Not a pointer parameter
{
byteValue++;
}
void setShortValue(uint16_t byteValue)//Not a pointer parameter
{
byteValue++;
}
int main()
{
uint8_t a = 123;
uint16_t b = 321;
SetFunction pointerFuncion;
SetFunction pointerFuncionShort;
//Typecast the setValue to appease compiler warning
pointerFunction.set_func = (void(*)(void*))&setValue;
pointerFuncionShort.set_func = (void(*)(void*))&setShortValue;
//use the function pointer with non-pointer parameter
// Compile ERROR thrown invalid conversion from uint8_t to void*
pointerFunction.set_func(a);
pointerFuncionShort.set_func(b);
}
Aprroach 2(causes a Too Many Parameters Compile Error)
typedef struct
{
void (*set_func)();//Blank parameter to allow multiple args
} SetFunction;
void setValue(uint8_t byteValue)//Not a pointer parameter
{
byteValue++;
}
void setShortValue(uint16_t byteValue)//Not a pointer parameter
{
byteValue++;
}
int main()
{
uint8_t a = 123;
uint16_t b = 321;
SetFunction pointerFuncion;
SetFunction pointerFuncionShort;
//Typecast the setValue to appease compiler warning
pointerFunction.set_func = (void(*)())&setValue;
pointerFuncionShort.set_func = (void(*)())&setShortValue;
//use the function pointer with non-pointer parameter
pointerFunction.set_func(a);// Compile ERROR thrown "Too many Args"
pointerFuncionShort.set_func(b);// Compile ERROR thrown "Too many Args"
}
UPDATE
To add clarity to the problem.
I have 100's of functions with 1 parameter.
The 1 parameter of the functions are different types.
I can't change any of the functions, but I want to have 1 function pointer type(or more based on type) to any of the functions.
I can change any of the types associated with the function pointer and the type to the function pointer, but not what it is pointing too.
No, it is not.
Simple answer: The called function does not know how to even fetch the argument.
Details: The function code is already fixed when it is called (executed). So it contains code to access the argument, which depends on the type of the arguemtn (e.g. for an uint32_t, a 32 bit load/soter is required, for an uint8_t an 8 bit load/store). So it cannot handle even the value fetch properly.
Different from C++ and higher languages like Python, C does not have a concept of run-time type identification built-in.
However, you can pass a union to the function and handle each variant in the function seperately. That would generate all possible accesses. However, you have to specify which actual type is being passed. This is normally done by a second argument which specifies the actual type.
That union could also be a struct composed of the type-identifier and the actual value. But that is just an envelope, everything is still explicit.
typedef union {
int i;
float f;
} MyValue;
typedef enum {
MY_VALUE_int,
MY_VALUE_float
} MyValueType;
void func(MyValueType type, MyValue value)
{
switch ( type ) {
...
}
}
int main(void)
{
func(MY_VALUE_int, (MyValueType){ .i=1 });
}
The compound literal argument only works for constants, otherwise you have to assign the value to a union first (or just use that union).
gcc has an extension to avoid this, so you can have a function which takes such a union, but the caller may use a simple cast, instead of a compound literal. That works for variables, too:
func(MY_VALUE_float, (MyValueType)1.0);
An alternative would be passing a const void * and internally casting. However, that is even more risky than the union approach.
All approaches require pasing the actual type explicitly (e.g. using an enum).
C11 allows to create a macro which evaluates different expressions, according to the type of an argument using the new _Generic construct. With that the original approach can be simulated (using gcc extension, normal way is possible, but more complicated):
// use the code of the first block here
#define func_generic(val) _Generic((val), \
int : func(MY_VALUE_int, (MyValueType)(val)), \
int : func(MY_VALUE_int, (MyValueType)(val)) )
// and call like:
func_generic(1);
func_generic(1.0);
However, note the restriction of _Generic: No two compatible types are allowed for the type-selector (i.e. const int and int are not allowed both) for uint16_t and uint32_t this works, however.
Note that gcc (you apparently use) supports C11 using -std=c11 or std=gnu11. The latter also enables GNU-extensions.
The short answer is no.
You have several problems:
1) The different functions all have to have the same signature to allow the function pointer to point to them.
2) The functions are taking their args by value which means a copy will be passed in and any actions you take on the value will not appear to have any affect outside the function call. Since you don't allow pointers I cant see any way round this.
If you are not bothered about problem 2 then you could try declaring a variadic function which will accept args of any type.
e.g.
void doSomethingWithValue(enum MyType type ...)
{
va_list args;
va_start( args, type);
switch( type)
{
case Uint8Type:
{
uint8_t value = va_arg(args, uint8_t);
//doSomething to value
}
break;
.
.
.
}
va_end(args);
}
Where MyType is an enum set up to identify which type is passed in.
which is used like so:
uint8_t value = 7;
doSomethingWithValue(Uint8Type, value);
//note that value is still 7
Note that both of your exampels exibit Undefined Behaviour because you call a function through a pointer of another (function) type.
I found a solution that relies on the fact that there are a limited number of function types known in advance. I think however that it is too much hassle. Just call the original function.
enum GFType {
GF_UINT8,
GF_UINT16 // etc
};
struct GenericFunction {
void (*func)(void);
GFType type;
};
void callGenericFunction(GenericFunction func, uint64_t p) // largest type
{
switch (func.type) {
case GF_UINT8:
((void (*)(uint8_t))func.func)(p);
return;
case GF_UINT16:
((void (*)(uint16_t))func.func)(p);
return;
default:
assert(1); // unimplemented function type
}
}
void setValue(uint8_t byteValue) // Not a pointer parameter
{
byteValue++;
}
void setShortValue(uint16_t byteValue) // Not a pointer parameter
{
byteValue++;
}
int main() {
uint8_t a = 123;
uint16_t b = 321;
GenericFunction pointerFunction;
GenericFunction pointerFunctionShort;
pointerFunction.func = (void (*)(void))setValue;
pointerFunction.type = GF_UINT8;
pointerFunctionShort.func = (void (*)(void))setShortValue;
pointerFunction.type = GF_UINT16;
callGenericFunction(pointerFunction, a);
callGenericFunction(pointerFunctionShort, b);
return 1;
}
Note that
a function-pointer may be freely converted to any other
function-pointer type and back again, and you will get the original
pointer.
This is what we use. We can't even use void * (because it is a data pointer, not a function pointer) to store the function pointer. So I used void (*)(void) to store the function pointer. An enum tells us to what kind of function we must convert it when we need to cal it.
If you can use C11, there is a way to do this using _Generic:
#include <stdio.h>
#include <inttypes.h>
#define setvalue_generic(x) _Generic((x), \
uint8_t: setValue, \
uint16_t: setShortValue \
)(x)
void setValue(uint8_t byteValue)
{
printf("setValue: %" PRIu8 "\n", byteValue);
byteValue++;
}
void setShortValue(uint16_t byteValue)
{
printf("setValue: %" PRIu16 "\n", byteValue);
byteValue++;
}
int main(void)
{
uint8_t a = 123;
uint16_t b = 321;
setvalue_generic(a);
setvalue_generic(b);
return 0;
}
Seems to work well with gcc -std=c11 -pedantic -Wextra -Wall.
#bolov answer is good for handling the different types, this is just a different way of handling the same issue, but with 1 parameter.
The downside to this approach is that the type in main has to be GENERAL_TYPE. In my application I can change the type of the parameter, but I can change the type of the functions that I'm pointing to.
the (void(*)(GENERAL_TYPE))& handles the function's parameter types, and the Union handles the types of all the different sizes.
Another option is to have function pointers for each type too.
typedef union generalType
{
uint8_t byteData;
uint16_t shortData;
uint32_t intData;
int integerData;
uint64_t longData;
void * voidData;
//Add any type
} GENERAL_TYPE;
typedef struct
{
void (*set_func)(GENERAL_TYPE);
} SetFunction;
void setValue(uint8_t byteValue)//Not a pointer parameter
{
byteValue++;
}
void setShortValue(uint16_t byteValue)//Not a pointer parameter
{
byteValue++;
}
int main()
{
GENERAL_TYPE a.byteData = 123;//restricted to use GENERAL_TYPE here
GENERAL_TYPE b.shortData = 321;
SetFunction pointerFuncion;
SetFunction pointerFuncionShort;
//Typecast the setValue parameter to be a general type will
//Allow it to send the data of whatever type.
pointerFunction.set_func = (void(*)(GENERAL_TYPE))&setValue;
pointerFuncionShort.set_func = (void(*)(GENERAL_TYPE))&setShortValue;
//use the function pointer with non-pointer parameter
pointerFunction.set_func(a);
pointerFuncionShort.set_func(b);
}
I'm looking for something similar to C++'s boost::bind but in C. What I want is to be able to:
bound_function = bind(my_function, some_param);
and have:
bound_function(something);
execute
myfunction(some_param, something);
So basically, whatever is bound to the function pointer will always be passed as the first parameter to the function.
Is there any way to do this in C?
Don't do this at home kids.
You couldn't do it the way C++ does it, because in boost::bind's case, a class is generated using TMP that holds the actual bound value.
I'm not aware of any way to accomplish anything similar in C. Most C APIs with callbacks like this will pass around a void * for your use to get around issues like this.
The closest you can get is something like this:
#include <stdio.h>
#include <stdlib.h>
typedef void (*function)(void*);
typedef struct {
void *arg;
function fn;
} binder;
binder *binder_create(function fn, void *arg)
{
binder *b = malloc(sizeof(binder));
if (b) {
b->fn = fn;
b->arg = arg;
}
return b;
}
void binder_delete(binder *b)
{
free(b);
}
void binder_exec(binder *b)
{
b->fn(b->arg);
}
int main(void)
{
binder *myfunc = binder_create((function)puts, "Hello, World!\n");
binder_exec(myfunc);
binder_delete(myfunc);
return 0;
}
It doesn't give you function call like syntax (you need to call binder_exec instead), and you would probably need to create several versions that take more arguments and arguments of different types.
In a word, no. C has no such concept.
I've declared many functions in one driver, and am passing the pointers to the functions to another driver in a list with the node format:
struct node
{
char def_prototype[256]; //example:(int (*)(wchar, int, int))
void *def_function;
};
Is there a way to typecast def_function to the prototype given in def_prototype?
Currently I'm using simple switch and strcmp, but I wanted to generalize it if possible.
PS: I know that casting between void pointer and function pointer is unsafe (as mentioned in various places in SO), but desperate times call for desperate measures and I have taken lot of care.
EDIT:
Sorry for the lack in clarity. I want to actually call the function (not just cast it), making a function pointer at runtime based on the char[] provided.
EDIT AGAIN:
Since I'm working at the kernel level (windows driver), I don't have access to much resources, so, I'm sticking to my current implementation (with some changes to kill back-doors). Thanks to all for your help.
ISO-C does not allow casting between function and data pointers, ie you should use a void (*)(void) instead of a void * to hold your function.
That aside, YeenFei is correct in his assertion that there is no general platform-independant solution, meaning the best you can do in C itself is to supply a list of supported signatures.
You should implement your own encoding scheme instead of using plain C prototypes. It's common to use a string where each char represents a function argument (and the first one the return value); a function of type int (*)(wchar, int, int) for example could have the signature "iwii".
Signature lookup tables can then be easily built using bsearch() and strcmp(); here's a complete example:
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int cmp(const void *key, const void *element)
{
return strcmp(key, *(const char * const *)element);
}
static _Bool dispatch(const char *sig, void (*func)(void), void *retval, ...)
{
// supported signatures; must be ordered according to strcmp()
static const char * const SIGS[] = { "iii", "v", "vi" };
const char * const *match = bsearch(
sig, SIGS, sizeof SIGS / sizeof *SIGS, sizeof *SIGS, cmp);
if(!match) return 0;
va_list args;
va_start(args, retval);
switch(match - SIGS)
{
case 0: { // iii
int a1 = va_arg(args, int);
int a2 = va_arg(args, int);
int rv = ((int (*)(int, int))func)(a1, a2);
if(retval) memcpy(retval, &rv, sizeof rv);
break;
}
case 1: { // v
func();
break;
}
case 2: { // vi
int a1 = va_arg(args, int);
((void (*)(int))func)(a1);
break;
}
default:
assert(!"PANIC");
}
va_end(args);
return 1;
}
// example code:
static int add(int a, int b)
{
return a + b;
}
int main(void)
{
int sum;
dispatch("iii", (void (*)(void))add, &sum, 3, 4);
printf("%i", sum);
return 0;
}
unless you want to mess with assembly thunking (pushing data onto stack before jumping, etc), there is better way other than doing some switch case.
if the destination function is finite and known, why not create a lookup table (map<string, functor>) for it ?
A good implementation of similar ideas is libffi. This implements the gory details of declaring and calling functions with arbitrary calling conventions and signatures. It is (surprisingly) platform portable, and known to work on Linux and Windows out of the box.
An example of its use is the Lua extension library alien. That demonstrates calling arbitrary functions declared at runtime and adapting from native Lua types to the types required for the calling conventions. The specific Lua binding won't be useful to you, but it serves as a complete working example of how and why one might actually use libffi.
Since C has no runtime type information, there is absolutely no need to do a dynamic cast as you are considering. Just pass the pointer and if everything fits, it will work. If the pointer doesn't point to a function with the right signature, there is no way to fix it.
There are basically two solutions:
Go to the assembly level and parse the prototype string there and put the arguments you find in the prototype there where the other function will expect them.
Make a long list of all supported prototypes and compare the current one with the list. When you find a match, you can make the typecast as needed. The most common structure for this test would ba an if-else ladder.