As a macro argument in C

I do not know if this is possible, I want to pass a block of instructions in the macro as an argument. I will show you an example:

#define ADD_MACRO(size, BLOCK){ for(int i=0; i<size; i++){\ BLOCK} } 

What do you think about it?

thanks for the help

0
source share
3 answers

The only problem with this macro is that it does not process commas in BLOCK . Commas are allowed with a macro variable:

 #define ADD_MACRO(size, ...) do { for(int i=0; i<size; i++){\ __VA_ARGS__} } while(0) 

(In addition, a common practice is to enclose operator macros in do … while(0) to force the user to include a semicolon.)

(Of course, the original problem may have a better solution. A preprocessor is a dumb tool. It is a preprocessor solution to the question posed.)

+2
source

You can do this by simply specifying a block in a macro or using a variable macro, as suggested in another answer. However, I would not recommend using macros for this purpose, since it usually makes the code less readable, more error prone and harder to read / maintain.

Instead, for general programming, consider using function pointers corresponding to the desired functionality.

Another option is to use the C11 _Generic macro to create safe, generic type code. Example:

 #include <stdio.h> #include <ctype.h> void int_increase (int* item) { (*item)++; } void char_increase (char* item) { (*item)++; } void int_print (int* item) { printf("%d ", *item); } void char_print (char* item) { printf("%c", *item); } void int_clear (int* item) { *item = 0; } void char_clear (char* item) { *item = '\0'; } void int_traverse (int* data, size_t size, void(*action)(int*)) { for(size_t i=0; i<size; i++) { action(&data[i]); } } void char_traverse (char* data, size_t size, void(*action)(char*)) { for(size_t i=0; i<size; i++) { action(&data[i]); } } #define do_something(data, size, action) \ _Generic((data), int* : int_traverse, \ char* : char_traverse) \ ( (data), (size), _Generic((data), int*: int_ ## action , char*: char_ ## action ) ) int main (void) { int int_data [] = {1, 2, 3, 4, 5}; do_something(int_data, 5, increase); do_something(int_data, 5, print); printf("\n"); do_something(int_data, 5, clear); do_something(int_data, 5, print); printf("\n"); char char_data [] = "ABCDE"; do_something(char_data, 5, increase); do_something(char_data, 5, print); printf("\n"); do_something(char_data, 5, clear); do_something(char_data, 5, print); printf("\n"); return 0; } 

Output:

 2 3 4 5 6 0 0 0 0 0 BCDEF 

Just add more similar features if you need to use other types.

+1
source

thks for all, especially Potatosmatters, so I follow your directives and I would like to resume your answer to a little code that might be useful to others:

 #define CALL_MACRO(size,instructions){ for(int i=0;i<size; i++){\ instructions ;} } ...... //put whatever you want into 'instructions' CALL_MACRO(100,for(int y=0; y<3; y++){ (inst1); (inst2);..} ); CALL_MACRO(100,(other inst1);(other inst2);.. ); 

So the result of CALL_MACRO depends on what you insert as instructions.

0
source

All Articles