Variable parameter lists in C ++ and C

I am working on rewriting a C program in C ++ to take advantage of the OO aspects, so it can easily support multiple devices, and one part of the program is an expression evaluator. Expressions can have function calls, but here is the structure for functions.

typedef struct { char *name; int argc; void (*func) (); } FUNCTION; 

Somehow func can have a variable number of arguments passed through it.

 RESULT *param[10]; if (Root->Function->argc < 0) { /* Function with variable argument list: */ /* pass number of arguments as first parameter */ Root->Function->func(Root->Result, argc, &param); } else { Root->Function->func(Root->Result, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], param[8], param[9]); } 

I don’t even know how to do this in C, to be honest. An explanation would be excellent. Can this be done in C ++?

+4
source share
5 answers

var args is what you are looking for. It works in both C and C ++. This is what is used for printf() , for example :).

You can find additional information googling va_arg (one of the functions used for a variable number of arguments)

+8
source

In fact, I'm going to go against everyone here, and your desire.

The ellipsis is wrong. This was considered indispensable in C, but since then we have learned better.

In fact, in C ++ there are actually better ways to use objects and, for example, function objects.

What you are looking for is a Command Pattern .

Create a base class called "Command" (an interface with the execute () method), then for each of the "functions" that you would like to add to "void (* func) ()", you create a derived class.

Your code will now look like this:

 std::vector<RESULT*> param(10, NULL); if (Root->Function->argc < 0) { /* Function with variable argument list: */ /* pass number of arguments as first parameter */ Command1* aCommand = new Command1(Root->Result); aCommand->set(Root->Result, argc, &param); Root->Function->command = aCommand; Root->Function->command->execute(); } else { Command2* aCommand = new Command2(Root->Result); aCommand->set(Root->Result, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], param[8], param[9]); Root->Function->command = aCommand; Root->Function->command->execute(); } 

Here you don’t need ellipsis, because each command object is specialized and knows exactly what parameters it needs (number and types).

The command template allows you to take full advantage of the "..." (ellipsis) without its inconvenience. Well, of course, some will say that it’s a waste of time, since they don’t make mistakes, so they don’t need to enter more ... unfortunately, I'm not so smart, so I prefer to define restrictions (quantity, types, statements), and let the compiler provide them for me.

+5
source

You can do this in C ++ using ... in the argument list. Look here for an explanation. But I think it would be better if you just pass the vector to the param function.

+1
source

Remember that a function is just another address that, when called by start, takes input from the stack. So, when you declare a FUNCTION, you simply save the address of this function. With this address, the function could be called later with various parameters. Yes, this can be done in C ++ using argument lists, however the implementation depends on how you want it to handle it.

0
source

Personally, when it comes to evaluating an AST for an expression, I tend to use a domain-specific language to generate a hierarchy of AST node structures and a set of multi-send operations for me. I have my own DSL for this, but the idea was stolen from treecc . A lot of problems go away because you don't need to have a single node class or a single evaluation function

treecc can generate C or C ++ (or several other languages) IIRC output. This is very similar to using flex or bison. The generated code is a bit naive, and you will soon eventually want more control over inheritance, but it works very well.

0
source

All Articles