4

Macro "VER" is defined as "((u_long)1)" in some other header file which I can't change.

In my code I need to compose function "test_1" using "test" and the VER. However compiler reported error since it was the "test_((u_long)1)" instead of "test_1" generated.

My question is: How to write macro so that it can generate "test_1"?

Thanks in advance!

#define VER ((u_long)1)      /* This is defined in some other header file which I can't change*/

#define paste(x, y, z) x ## y ## z
#define paste2(x, y, z) paste(x, y, z)
#define fcall(fname) paste2(fname, _, VER)

int test_1() {
  return 0;
}

int main() {
  fcall( test )();
  return 0;
}

3 Answers 3

6

I can't guarantee it's 100% portable, but it should work:

#define VER ((u_long)1)

#define STRIP1(x) STRIP2 x

#define STRIP2(x) STRIP3 x

#define STRIP3(x)

#define paste(x, y, z) x ## y ## z
#define paste2(x, y, z) paste(x, y, z)
#define fcall(fname) paste2(fname, _, STRIP1(VER))

Live example

It works by interpreting the parentheses inside the definition of VER as macro invocation. Here's the individual expansions, as they occur:

STRIP1(VER) // STRIP1 with argument VER

STRIP2 ((u_long)1) // STRIP2 with argument (u_long)1

STRIP3 (u_long)1  // STRIP3 with argument u_long, followed by 1

1

If we re-arrange the whitespace (it's insignificant anyway), we get this:

STRIP1(VER)

STRIP2((u_long) 1)

STRIP3(u_long) 1

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

3 Comments

That is very cool. But if someone changes the definition of VER (say to (1)), it breaks.
@brianbeuning Of course. But then again, normally during development you are aware when "external code I can't modify" changes (e.g. because you've upgraded to a new version), so you can adapt the STRIP macros accordingly.
@hhwangcocora You might want to mark the answer as accepted, then (using the green tick-mark next to it). That's how SO works.
0

With that source, you probably can't, since macro expansion is textual, so the ((u_long)1) can not possibly become 1.

One solution would of course be to actually write some code to print the actual value of VER. The other alternative is to convince the people that own the file you can't change that they should change it for you...

Comments

0

As modified Angew version

#define VER ((u_long)1)

#define _(x) x
#define id(x) _(x)

#define STRIP3(x)
#define STRIP2(x) id(STRIP3 x)
#define STRIP1(x) id(STRIP2 x)

#define paste(x, y, z) x ## y ## z
#define paste2(x, y, z) paste(x, y, z)
#define fcall(fname) paste2(fname, _, STRIP1(VER))

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.