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

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.