0

I have a structure and i am using preprocessing macro to populate the arrays in struct.

#include <stdio.h>
void init_data();
typedef struct _abc{
        int a[10][10];
        int b[5][5];
}abc;
static abc q_abc[]= {
                #define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
                 XYZ(1,2,3)
                 XYZ(1,3,2)

};
static abc q_abc1[5];
void init_data()
{
 #define XYZW(x,y,z) q_abc1[x].a[y][z] =1;
  XYZW(1,2,3)
  XYZW(1,3,2)
}
int main()
{
        printf("\n  %d  %d\n",q_abc[1].a[2][3]);
        init_data();
        printf("\n %d  %d\n",q_abc1[1].a[2][3]);
        return 0;
}

I am initializing struct q_abc using macro. But the problem here is value set during macro call to XYZ(1,2,3) is reset to the default 0 during call to next macro call XYZ(1,3,2). I can understand as not specifying any explicit initializer will set the array to the default 0.

To avoid this I used the init_data approach .Here i am not initializing the array but assigning, so arrays will have all the values from all macro calls intact. but then problem here is , if data is huge or number of macro calls are huge, the func call will take little time to complete which adds an overhead to my exe run time.

is there any way to achieve init_data sort of behavior during variable definition itself ? any suggestions ?

6
  • 2
    I have a superstitious skepticism about using #define within {}. What is your intended effect of placing them there? Commented Dec 19, 2018 at 8:39
  • 3
    dump the #define. Write it out long hand - makes it readable for a start. Commented Dec 19, 2018 at 8:41
  • I don't quite understand what you are saying, my intent to put #define XYZ(x,y,z) .. is to indicate that this macro is only and only used to init this structure (within which it is defined) and i intend to include a header file with all macro definitions X(1,2,3).. and so on. This is just a concept i intend to use in a bigger work project. Commented Dec 19, 2018 at 8:51
  • 1
    @CodeTry: since you are mentioning "huge arrays", one approach might be to write a script which will generate the source with the appropriate data for you during build (or even one-time invoke). That's far more efficient and less error prone than writing hundreds of numbers manually. Commented Dec 19, 2018 at 9:12
  • I agree, and so far what i have done is written a python script to parse the data to dump to header file in Xmacro format x(1,2,3,...) . And then i lam trying to load my arrays during preprocessing. I only added a sample code to highlight the exact problem but then as StoryTeller tells me its not much gain w.r.t to time. Commented Dec 19, 2018 at 10:33

1 Answer 1

3

This is a case where turning on warnings would have helped you. Compiling your code with GCC gives me this:

main.cpp:8:40: warning: initialized field overwritten [-Woverride-init]
                 #define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
                                        ^
main.cpp:10:18: note: in expansion of macro 'XYZ'
                  XYZ(1,3,2)
                  ^~~
main.cpp:8:40: note: (near initialization for 'q_abc[1]')
                 #define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
                                        ^
main.cpp:10:18: note: in expansion of macro 'XYZ'
                  XYZ(1,3,2)

And for good reason. A brace initializer will initialize all the fields, even if you omit explicit initializers for some (those will be zero). By writing X(1,..) X(1,...) you initialize the same index twice. You can't split it into two macro expansions like you try. It must be in a single one, if you really wish to use a macro.

Personally, I wouldn't faff about with macros. Designated initializers make the code readable enough even without hiding them behind a macro.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks , and i already know the reason why they become zero . I wanted to ask if theres any macro trick that can do away with that so that it does not put zero there but the last value from the earlier macro call.
@CodeTry - This is a rabbit hole you don't want to go into. Honestly, the cost/benefit ratio just isn't worth it to make the preprocessor do this.
Okay , got it. Thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.