problems using defines inside macros

closed account (236Rko23)
hi there, i'm doing something in C where i needs to modify an initializer at compile time.
1
2
3
4
5
6
7
#define _PCN 3
struct SOMETHING_t {
   uint8_t variableA;
   float   variableB[_PCN];
   uint8_t variableC[_PCN];
   uint8_t variableD;
}


and the declaration with the initializer
1
2
3
4
5
6
struct SOMETHING_t stuff = {\
    8,\
    {1.0,1.0,1.0},\
    {3,3,3},\
    2\
};


the problem is that i want it to change by changing _PCN so i made some macros.

1
2
3
4
5
6
#define	InitxN(a) _InitxN(a,_PCN)
#define _InitxN(a,b) Initx ## b(a)

#define Initx1(a) a
#define Initx2(a) {a,a}
#define Initx3(a) {a,a,a} 


so that it would like this
1
2
3
4
5
6
struct SOMETHING_t stuff = {\
    8,\
    InitxN(1.0),\
    InitxN(3),\
    2\
};


but i can't figure how to do the macro so that it expands _PCN before passing it to the next one, it ends up as Initx_PCN(a) instead of Initx3(a). I've read the gnu gcc page but cant find something about this. There's about macro inside macro but not about define inside macro...

any idea?
Last edited on
closed account (236Rko23)
anyone?
I do not think a single preprocessor pass will accomplish this. Try a multi pass by just issuing a preprocess command before you do your normal compile and link. You can do this on gcc with "gcc -E mycode.c" . Then do a normal build.
closed account (236Rko23)
@cppbuser
it wasn't neccessary to do multipass, but that command sure helped me. I used it to see the actual output from the preprocesor rather than just the blablabalerrorhere

also found a little help here in case someone is also interested
http://stackoverflow.com/questions/1597007/creating-c-macro-with-and-line-token-concatenation-with-positioning-macr

the solution was to add some extra levels to the macro to give it a chance to expand
1
2
3
4
5
6
7
8
9
10
#define Initx1(a) a
#define Initx2(a) {a,a}
#define Initx3(a) {a,a,a}
#define Initx4(a) {a,a,a,a}

#define __InitxN(a,b) Initx ## a (b)

#define	_InitxN(a,b) __InitxN(a,b)

#define	InitxN(a) _InitxN(_PCN,a)  


thanks for the help
right .. I just did this simple example. Basically you just need to use "that" to call "this". Without "that", "this" will produce CSOME and fail.

#include <stdio.h>

#define CAT 1234
#define SOME AT
#define this(a, b) a ## b
#define that(a, b) this(a,b)


int main() {

printf("%d\n",that(C, SOME));

return 0;
}
also if you do want to multi pass, (things that will horrify your CS professor) you can do something like this. It fails on 1 pass, compile, and link, but with 2 pass, compile, and link it works fine. This opens up a lot of interesting possibilities if you start using conditionals. Perhaps you can do a lot of cpp stuff with ordinary c ...

#define FIRST #define SECOND 9999
#define BLUE 52
#define REDGREEN BLUE
#define RED 51
#define COLOR(a,b) a##b

int main() {

FIRST

printf("%d\n",COLOR(RED,GREEN));

return 0;
}
Last edited on
Topic archived. No new replies allowed.