Is it possible to set values for default parameters in C? For example:
void display(int a, int b=10){
//do something
}
main(){
display(1);
display(1,2); // override default value
}
Visual Studio 2008, complaints that there is a syntax error in -void display(int a, int b=10). If this is not legal in C, whats the alternative? Please let me know. Thanks.
Default parameters is a C++ feature.
C has no default parameters.
It is not possible in standard C. One alternative is to encode the parameters into the function name, like e.g.
void display(int a){
display_with_b(a, 10);
}
void display_with_b(int a, int b){
//do something
}
There are no default parameters in C.
One way you can get by this is to pass in NULL pointers and then set the values to the default if NULL is passed. This is dangerous though so I wouldn't recommend it unless you really need default parameters.
Example
function ( char *path)
{
FILE *outHandle;
if (path==NULL){
outHandle=fopen("DummyFile","w");
}else
{
outHandle=fopen(path,"w");
}
}
Not that way...
You could use an int array or a varargs and fill in missing data within your function. You lose compile time checks though.
If you are using a compiler compatible with C++2a, then there is a preprocessor trick that you can use, as explained at https://stackoverflow.com/a/10841376/18166707
You can use this code snippet as an example:
#include <stdio.h>
#define ADD_THREE(a,b,...) add_three_nums(a, b, (0, ##__VA_ARGS__))
int add_three_nums( int a, int b, int c)
{
return a + b + c;
}
void main( void )
{
printf("%d\n", ADD_THREE(3, 5));
printf("%d\n", ADD_THREE(4, 6, 8));
}
Related
Say I had a program where the user could select a number between 0-10. Each number would then correspond to the calling of a certain function. In Python, I know I could just create an array of function names, index into it with the selected option, and then call the function. How would I implement this in C? Or is it even possible?
Here is an example how to do it. Please note that all functions must have the same signature, but of course you can change that from my funptr type to for example a function that has void return or takes a char and not two ints.
// Declare the type of function pointers.
// Here a function that takes two ints and returns an int.
typedef int (*funptr)(int, int);
// These are the two functions that shall be callable.
int f1(int a, int b) { return a + b; }
int f2(int a, int b) { return a - b; }
// The array with all the functions.
funptr functions[] = {
f1,
f2,
};
// The caller.
int call(int i, int a, int b)
{
return functions[i](a, b);
}
The only problem that I can see in the solution from above is that there is no check for the array index (you may get some tricky problems).
To make the code more robust, you can add a check for the index (boundaries), like
add one if statement inside of function "call" where you check the parameter i (not to be bigger than the maximum value)
I have a struct that contains a declaration like this one:
void (*functions[256])(void) //Array of 256 functions without arguments and return value
And in another function I want to define it, but there are 256 functions!
I could do something like this:
struct.functions[0] = function0;
struct.functions[1] = function1;
struct.functions[2] = function2;
And so on, but this is too tiring, my question is there some way to do something like this?
struct.functions = { function0, function1, function2, function3, ..., };
EDIT: Syntax error corrected as said by Chris Lutz.
I have a struct that contains a declaration like this one:
No you don't. That's a syntax error. You're looking for:
void (*functions[256])();
Which is an array of function pointers. Note, however, that void func() isn't a "function that takes no arguments and returns nothing." It is a function that takes unspecified numbers or types of arguments and returns nothing. If you want "no arguments" you need this:
void (*functions[256])(void);
In C++, void func() does mean "takes no arguments," which causes some confusion (especially since the functionality C specifies for void func() is of dubious value.)
Either way, you should typedef your function pointer. It'll make the code infinitely easier to understand, and you'll only have one chance (at the typedef) to get the syntax wrong:
typedef void (*func_type)(void);
// ...
func_type functions[256];
Anyway, you can't assign to an array, but you can initialize an array and copy the data:
static func_type functions[256] = { /* initializer */ };
memcpy(mystruct.functions, functions, sizeof(functions));
I had the same problem, this is my small program to test the solution. It looks pretty straightforward so I thought I'd share it for future visitors.
#include <stdio.h>
int add(int a, int b) {
return a+b;
}
int minus(int a, int b) {
return a-b;
}
int multiply(int a, int b) {
return a*b;
}
typedef int (*f)(int, int); //declare typdef
f func[3] = {&add, &minus, &multiply}; //make array func of type f,
//the pointer to a function
int main() {
int i;
for (i = 0; i < 3; ++i) printf("%d\n", func[i](5, 4));
return 0;
}
You can do it dynamically... Here is a small example of a dynamic function array allocated with malloc...
#include <stdio.h>
#include <stdlib.h>
typedef void (*FOO_FUNC)(int x);
void a(int x)
{
printf("Function a: %d\n", x);
}
void b(int x)
{
printf("Function b: %d\n", x);
}
int main(int argc, char **argv)
{
FOO_FUNC *pFoo = (FOO_FUNC *)malloc(sizeof(FOO_FUNC) * 2);
pFoo[0] = &a;
pFoo[1] = &b;
pFoo[0](10);
pFoo[1](20);
return 0;
}
From the top of my head and untested.
// create array of pointers to functions
void (*functions[256])(void) = {&function0, &function1, &function2, ..., };
// copy pointers to struct
int i;
for (i = 0; i < 256; i++) struct.functions[i] = functions[i];
EDIT: Corrected syntax error as said by Chris Lutz.
You could do that while declaring your struct instance:
function_structur fs = { struct_field1,
struct_field2,
{function0, function1, ..., function255},
struct_field3,
... };
You cannot use this shortcut for initialize arrays after the array has been declared: if you need to do that, you'll have to do it dynamically (using a loop, a memcpy or something else).
If you want to post-initialize an array using form like {func1, func2, ...}, this can be accomplished in the following way (using GCC):
UPD (thanks to Chris Lutz for remarks)
Define a macro like this:
#define FUNCTION_VECTOR_COPY(destVec, sourceVec) memcpy(destVec, sourceVec, sizeof(sourceVec))
And pass source vector using Compound Literals, as follow:
#include <string.h>
...
void (*functions[256])();
...
FUNCTION_VECTOR_COPY (functions, ((void(*[])()) {func1, func2, func3}));
I'm trying to achieve something like this:
void sum(int a, int b){ printf("result: %d", a+b); }
void callFunc(void (*funct)(...), ...)
{
va_list ars;
va_start(ars, funct);
funct(ars);
va_end(ars);
}
int main()
{
callFunc(sum, 2,3);
return 0;
}
But this doesn't work, because of needing of two va_lists, for funct params and arguments passed. However, even if i try to pass the sum function, it says:error: invalid conversion from 'void (*)(int, int)' to 'void (*)(...)'
So how to make this work good old C-style?
You can't do it like that. It's just simply not possible.
The best you can do (while keeping it generic) is change funct to take a va_list, much like vprintf. But that probably won't work very well for your purposes.
Alternatively, you can do a macro:
#include <stdio.h>
#define CALL_FUNC(func, ...) func(__VA_ARGS__)
void sum(int a, int b){ printf("result: %d", a+b); }
int main()
{
CALL_FUNC(sum, 2, 3);
return 0;
}
I have done some research about how to use function pointers in C and I was trying to do some model of an object-oriented kind of thing. So to model such a thing I have been told I would have to add function pointers to the structs, so that they would be kind of 'an object'.
As I am pretty new on programming in C, this question may seem a little stupid (or very easy to answer), but on the Internet, I just found examples concerning C++ and that's not what I am searching.
Here is an example I would like to show, so that you can easily understand what my question is about:
try.h-file:
struct thing {
void (*a)(int, int);
};
void add(int x, int y);
try.c-file:
#include <stdio.h>
#include <stdlib.h>
#include "try.h"
void add(int x, int y) {
printf("x + y = %d\n", x+y);
}
int main(int argc, char* argv[]) {
struct thing *p = (struct thing*) malloc(sizeof(struct thing));
p->a = &add;
(*p->a)(2, 3);
free(p);
p = NULL;
return 0;
}
As an example I would want to have always x = 2, so the function pointer in struct thing would be this kind of pointer: void (*a)(int) and not void (*a)(int, int) anymore.
How can I bind the argument x = 2 when passing the function pointer to the struct (line p->a = &add;)? Is this even possible in C? In C++ I have seen something like std::bind, but I wasn't able to do this in C.
The function pointer has to have the same signature (type and arguments) as the function it points to, so you can't really do it like that.
You could wrap the bind and the call in another couple of functions:
struct thing {
void (*a)(int, int);
int x;
};
...
void bind1st( struct thing *p, int arg )
{
p->x = arg;
}
void call( struct thing *p, int arg )
{
p->a( p->x, arg );
}
You'll want to experiment with this a bit, but that should get you started.
I've had similar problems,and I used the following method to resolve, use gcc to compile it work, use clang to compile it do not work.
#include <stdio.h>
typedef int (*add_t) (int);
add_t add2(int x) {
int add1(int y) {
return x + y;
}
return add1;
}
int main() {
//add2(2);
printf("%d\n", add2(2)(3));
}
A way that no one have talked about yet is to use some JIT logic (I won't provide a working example right now, because I've not yet tried it, but I will use it at some time for a RPC library). This is not strictly speaking a C language feature, and it's feasible only on CPU/MCU architecture where you can write to an executable memory segment (it's possible on x86_64, x86, some ARMs etc.).
The principle is really just to construct a function dynamically that will call the wrapped function in a similar way python defines dynamically nested functions.
Some library you can use for it : libgccjit, libjit, gnu-ligthning, llvm etc.
I think this is the best solution .
typedef void(*call_type)();
call_type bind(void (*f)(int,int), int a, int b) {
void call() {
f(a,b);
}
return &call;
}
void f(int a, int b){
printf("%d, %d", a, b);
}
int main(){
call_type c = bind(f, 5, 4);
c();
}
I'm trying to write a mapping function that takes a function pointer, and passes it to another function, but gcc is yelling at me.
Here is an idea of what I'm trying to do.
void map(T thing, void apply(int a, int b, void *cl), void *cl);
void function(T thing, void apply(int a, int b, void *cl), void * cl)
{
for(int i = 0; i < 10; i++)
{
map(thing, apply, cl);
}
}
gcc's complaint:
warning: passing argument 2 of 'map' from incompatible pointer type
Any ideas?
In order to help with this problem we'd need to see the declaration / signature of the map function. Almost certainly there is a slight difference in the function signature. The easiest way to resolve this is to typedef out a function pointer type and use it in both functions.
typedef void (*apply)(int,int,void*);
You can't pass functions around. You need to pass pointers to functions instead.
void map(T thing, void (*apply)(int a, int b, void *cl), void *cl);
void function(T thing, void (*apply)(int a, int b, void *cl), void * cl)
{
/* ... */
map(thing, apply, cl);
/* .... */
}
It's just complaining that the function pointer type expected by map's second argument is different from that of apply. If you either change that type, or (if safe) cast, then it'll be fine.
It works for me with gcc 4.3.3 and -Wall.
While I think all versions of C that ever existed rewrote function "value" parameters to be pointers, you could use a more traditional declaration:
void function(T thing, void (*f)(int a, int b, void *cl), void * cl)
But, like I said, your example works fine for me, unchanged except for typedef int T, and map(1, ...)