Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to pass multiple values to macro function as single defined macro value in C?

Tags:

c

gcc

macros

avr

I want to declare pin definition in global header as a simple line like:

#define STATUS_LED B,7

Then I want to pass this pin definition to function above:

CMBset_out(STATUS_LED);

I don't know how to approach this - MY_PIN is in proper format to be replaced during precompilation phase.

#define CMBsbi(port, pin) (PORT##port) |= (1<<pin)
#define CMBset_out(port,pin) (DDR##port) |= (1<<pin)
// define pins 
#define STATUS_LED B,7

Then, I want to pass this pin definition to function above (hw_init_states() is declared in the same header file called from main C file):

// runtime initialization
void hw_init_states(){
#ifdef STATUS_LED
    CMBset_out(STATUS_LED);
#endif
}

But I get a compilation error:

Error   1   macro "CMBset_out" requires 2 arguments, but only 1 given   GENET_HW_DEF.h  68  23  Compass IO_proto
like image 886
bajtec Avatar asked Jul 26 '19 08:07

bajtec


People also ask

Can a macro call another macro in C?

Here is an example of how to run another macro from a macro using the Call Statement. Just type the word Call then space, then type the name of the macro to be called (run). The example below shows how to call Macro2 from Macro1. It's important to note that the two macros DO NOT run at the same time.

Can we pass arguments in macro definition?

Function-like macros can take arguments, just like true functions. To define a macro that uses arguments, you insert parameters between the pair of parentheses in the macro definition that make the macro function-like. The parameters must be valid C identifiers, separated by commas and optionally whitespace.

Can a macro define another macro?

You cannot define macros in other macros, but you can call a macro from your macro, which can get you essentially the same results.

How do you separate a multiline macro in C language?

We can write multiline macros like functions, but for macros, each line must be terminated with backslash '\' character. If we use curly braces '{}' and the macros is ended with '}', then it may generate some error.


2 Answers

It is possible, but you need another level of macros to expand the argument:

#define CMBset_out_X(port,pin) (DDR##port) |= (1<<pin)
#define CMBset_out(x) CMBset_out_X(x)

Of course this means that you can't use the CMBset_out macro with two explicit arguments.

like image 83
Some programmer dude Avatar answered Oct 11 '22 02:10

Some programmer dude


An improvement upon the previous answer, which also allows you to call the macro with two explicit arguments.

It should work with any c99 (or better) compiler:

#define CMBset_out_X(port,pin) (DDR##port) |= (1<<pin)
#define CMBset_out(...) CMBset_out_X(__VA_ARGS__)

#define STATUS_LED B,7
CMBset_out(STATUS_LED)
CMBset_out(B, 7)
like image 22
mosvy Avatar answered Oct 11 '22 02:10

mosvy