2
#define SATA_PORT_0 "/sata-ahci/port0" #define SATA_PORT_1 "/sata-ahci/port1" #define SATA_PORT_2 "/sata-ahci/port2" #define SATA_PORT_3 "/sata-ahci/port3" #define SATA_PORT_4 "/sata-ahci/port4" #define SATA_PORT_5 "/sata-ahci/port5" #define SATA_NODE(p) HOW TO DEFINE THIS?!! int main() { int i; for (i=0;i<6;i++) { printf("%s\n", i, SATA_NODE(i)); } return 0; } 

Question: how to define above macro, to get string print out in GCC ?

0

5 Answers 5

3

You can't readily do it with a macro.

The problem is that a macro is a compile time construct, and the loop you have there is a run time construct; you can't do it directly.

You could investigate Boost Preprocessor (which is not specifically for C++; it also works with the C preprocessor) and use that to write macros which generate the loop.

You could hand unroll the loop and use a macro with a constant argument:

#define SATA_PORT(i) "/sata-ahci/port" #i printf("%s\n", 0, SATA_PORT(0)); printf("%s\n", 1, SATA_PORT(1)); printf("%s\n", 2, SATA_PORT(2)); printf("%s\n", 3, SATA_PORT(3)); printf("%s\n", 4, SATA_PORT(4)); printf("%s\n", 5, SATA_PORT(5)); 

Or you can use an array of strings (also suggested by a now-deleted answer).

#define DIM(x) (sizeof(x)/sizeof(*(x))) const char * const sata_ports[] = { "/sata-ahci/port0", "/sata-ahci/port1", "/sata-ahci/port2", "/sata-ahci/port3", "/sata-ahci/port4", "/sata-ahci/port5" }; for (int i = 0; i < DIM(sata_ports); i++) printf("%d %s\n", i, sata_ports[i]); 
Sign up to request clarification or add additional context in comments.

1 Comment

#define SATA_NODE(p) ((p==0)?"/sata-ahci/port0":ISP1(p)) #define ISP1(p) ((p==1)?"/sata-ahci/port1":ISP2(p)) #define ISP2(p) ((p==2)?"/sata-ahci/port2":ISP3(p)) #define ISP3(p) ((p==3)?"/sata-ahci/port3":ISP4(p)) #define ISP4(p) ((p==4)?"/sata-ahci/port4":ISP5(p))
1

In the C language you can't. Macro substitution occurs before ordinary compilation. The preprocessor doesn't know that preprocessing token i is going to be declared as an int later during ordinary compilation.

Execution comes even later. The compiler can figure out that i is going to have values ranging from 0 to 5, but that doesn't help you. The actual assignments occur during execution, which is after compilation finished, which is after preprocessing finished.

Comments

1

Thanks for above answers. I found a way to do this myself.

#define SATA_PORT(p) (p==0)?SATA_PORT_0:ISP1 #define ISP1 (p==1)?SATA_PORT_1:ISP2 ... 

In some situations, the above macro makes the code much better.

1 Comment

Each to their own, I suppose. I wouldn't touch this with a bargepole, but it does work.
0

EDIT: I've made solution a little bit nicer (because of availability of compound statements in GCC compiler).

If i had similar problem I would solve it like this:

#define SATA_PORT(p) ({char prt[100]; sprintf(prt, "/sata-ahci/port%d", p); prt;}) 

And BTW you forgot printf format specifier for variable i.

Comments

0

Maybe this is what you need(ed):

#define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define SATA_NODE_TO_SATA_PORT(p) SATA_PORT_##p #define SATA_NODE(p) TOSTRING(SATA_NODE_TO_SATA_PORT(p)) 

Then, if you try to print the preprocessed macros with:

std::cout << SATA_NODE(3) << " - " << SATA_NODE(5) << std::endl; std::cout << SATA_NODE(7) << std::endl; 

what you get is:

"/sata-ahci/port3" - "/sata-ahci/port5" SATA_PORT_7 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.