0

i am writing HW code and required to crate one macro where user can pass different argument. My macro will make sure that each argument get written on some memory location.

#define my_macro (.......) { \
   int *data1 = (int *) addr1 ; \  #if args1 is present
   int *data2 = (int *) addr2 ; \ #if args2 is presnet
   .
   .
   *data1 &= args1;
   *data2 &= args2;
   .
   .
}

ex1 : my_macro(data1,data2); ex2 : my_macro(data1,data2,data3,data4);

also data1 and data2 should be declare only when args is present. ex. if args is not present my_macro(data1) that case *data1 &= args1; should not be get declare.

tired to use __VA_ARGS__ thing but dont know how to separate out different variable so i can assign each args to data*

Please help here!

vjain419
  • 243
  • 1
  • 3
  • 11
  • What do you mean if args is present? – this Jan 21 '14 at 13:16
  • like in above mention ex1, only data1 & data2 should get declare in macro `int *data1 = (int *) addr1 ;int *data2 = (int *) addr2 ;`. It would be not good if all data1,2,3,4 get declare even if not require. . – vjain419 Jan 21 '14 at 13:18
  • Got the solution here. http://stackoverflow.com/questions/21326523/getting-error-28-expression-must-have-a-constant-value-while-using-varidic Thanks to doug65536. – vjain419 Jan 27 '14 at 06:58

1 Answers1

2

There is an answer you can use from this question (the 3rd one): Is it possible to iterate over arguments in variadic macros?

I'd say something like:

#define my_macro (...) { \
do { \
    int i; \
    int _arr_args_[] = {__VA_ARGS__}; \
    for (i = 0; i < sizeof(_arr_args_)/sizeof(_arr_args_[0]); i++) \
        *(int *) addr_i &= _arr_args[i]; \
    } \
 } while(0)

This is equivalent to what you want to do; the only missing detail is exactly how you get addr_i - you didn't specify where this comes from, so I'll assume you just have some way to get it in your code. This, of course, assumes that the arguments you'll be passing are always of type int, which I guess is safe to assume, given the example you provided.

Community
  • 1
  • 1
Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
  • Thank you. addr is word aligned address so for each of i, i will add 0x4. let me try this solution. – vjain419 Jan 21 '14 at 13:48
  • I am getting below error when i try this macro in my code. ** Error: #969: the identifier __VA_ARGS__ can only appear in the replacement lists of variadic macros int _args[] = { __VA_ARGS__ };\ ** – vjain419 Jan 22 '14 at 05:01
  • it was my mistake..that error is gone.. now getting new error! `Error: #137: expression must be a modifiable lvalue UPDATE_DATA(MSG_3,DATA2);` what is possibility to get this error! – vjain419 Jan 22 '14 at 06:02
  • update :above error was because if wrong casting. Error is gone now. :) Lets see if its working with all my scenario or not! ;) – vjain419 Jan 22 '14 at 06:14
  • Ok ... I kind of lost myself here with so many errors, but I'm glad they're gone. If this works for you, don't forget to accept the answer :) – Filipe Gonçalves Jan 22 '14 at 10:03
  • Sure Filip. But seems like its not working... `_arr_args[i]` is not getting assigned to `addr_i`. I could mail you the code and calling of that macro if it is okay with you? – vjain419 Jan 22 '14 at 10:43
  • Assigning `_arr_args_[i]` to `addr_i` is not the intent of the code: the intent is to `AND` `addr_i` with `arg[i]`; that's what your example did, that's what this code will do. – Filipe Gonçalves Jan 22 '14 at 12:37
  • Thats what i did. see below is macro implementation. `#define UPDATE_DATA(bit,...) { \ do { \ int i; \ int j = 0; \ int _args[] = {__VA_ARGS__};\ int *addr = (int *) ADDR ; \ for (i = 0; i < sizeof(_args)/sizeof(_args[0]); i++) {\ *(int *) (DATA_ADDR - j) &= _args[i];\ j = j + 0x4; \ }\ *addr |= 1 << bit;\ }while (0); \ }` as i am working on HW coding i can see Wavedump where i could not see that any of _args[i] is getting written in expected address.i.e DATA_ADDR – vjain419 Jan 23 '14 at 03:54
  • Just to add I called this macro like `1) UPDATE_DATA(1,data1)` `2) UPDATE_DATE(2,data2,data3)`. But seems like _args[] is empty...because i could see write is happening on DATA_ADDR but its writting 0x0 not data1 or data2 or data3 which i am expecting.. – vjain419 Jan 23 '14 at 05:11
  • What's the type of `data1`, `data2`, etc.? – Filipe Gonçalves Jan 23 '14 at 12:11
  • `#define data1 0xa5` `#define data2 0x55` i think data1 & data2 are of int type right?? – vjain419 Jan 23 '14 at 14:22
  • @vjain419 The code works. You are probably passing wrong values in the arguments and the `AND` becomes `0`. Please post a compilable snippet of your code in ideone.com, or any similar website, and let us see. You might as well want to open a new question about this to avoid extended discussions in the comments section. – Filipe Gonçalves Jan 23 '14 at 16:53
  • Your guess was right.. while doing `&=` it was doing read and `&` with read value.. so my first read data was always 0 so whatever `data1` & `data2` i `AND` with with `read_data` it become 0! so i tried `|=` and it worked!.. Thank you – vjain419 Jan 24 '14 at 05:15
  • ,is it limitation of using macro. While using above macro if i try to use it like `msg_id = MSG_1; for(j=0; j<15 ; j++) { msg_id = msg_id +1; l_data = data_array[j]; UPDATE_DATA(msg_id,l_data,(SYSTEM_BASE_ADDR+offset)); } ` i am getting `Error: #28: expression must have a constant value` Error. – vjain419 Jan 24 '14 at 06:57
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/45983/discussion-between-vjain419-and-filipe-goncalves) – vjain419 Jan 24 '14 at 08:00