2

I am trying to implement VERSION macro for my program, that is to be changed under certain circumstances.

macro VERSION is defined via Makefile (git info is put there) and is a string. Now I have a set of #define'd switches and I want VERSION to reflect which of them are on. This looks now like the follows (main.h):

#define COMPLEX_DEPOSITION // This is switch. later in code it is used in #ifdef...#endif construction.

#ifdef COMPLEX_DEPOSITION
#define CD "_COMP_DEP" // this is the string I want to put in the end of VERSION
#define VERSION_ VERSION CD

#undef VERSION // this is to suppress 'macro redefinition' warning
#define VERSION VERSION_
#undef VERSION_
#endif

Well, I get a lot of errors, most of which make me think that C preprocessor works with lines in file in random order:(

Later I have an even more complex thing that is intended to make VERSION -> VERSION_WLT_GAP_2

#define WIRESLIFETIMES

#ifdef WIRESLIFETIMES
#define GAP 2
#define VERSION_ (VERSION ## "_WLT_GAP_" ## #GAP)
#define VERSION VERSION_
#undef VERSION_
#endif

and I got no idea what to do and if this is even possible

7
  • 1
    I suspect the easiest solution is #else #define CD ""- always concatenate the same macro's, but just define them to empty strings if not needed. Commented Jun 24, 2019 at 11:16
  • 2
    stackoverflow.com/questions/5256313/… Commented Jun 24, 2019 at 11:22
  • @SirJoBlack Thank you, I have seen this question and its solution does not work for me. Commented Jun 24, 2019 at 11:33
  • @MSalters Thank you, this solves the first problem but does not solve the second one Commented Jun 24, 2019 at 11:38
  • The problem with the second example appears to be circular logic. VERSION_ is defined in terms of VERSION and VERSION is then defined as VERSION_`. I don't even understand the real intent there. Commented Jun 24, 2019 at 11:55

2 Answers 2

6

String literals concatenate naturally when placed next to each other

"foo" "bar" is the same as "foobar".

As for the second example, you probably want:

#define CAT_(A,B) A##B
#define CAT(A,B) CAT_(A,B)

#define GAP 2
#define VERSION CAT(VERSION_WLT_GAP_ , GAP)

VERSION //expands to VERSION_WLT_GAP_2

I recommend playing with gcc -E/clang -E a bit, to learn how macros work, before trying to compose anything complex with them.

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

2 Comments

Thank you, but point is that VERSION macro holds a value that comes from Makefile
@Xtotdam Conditionally (#if) #undef it, then? I'm not proposing you make it as simple as this. I'm just presenting the core technique you could use.
1

Well, the answer seems to be the following:

// https://stackoverflow.com/questions/5256313/c-c-macro-string-concatenation
// Concatenate preprocessor tokens A and B without expanding macro definitions (however, if invoked from a macro, macro arguments are expanded).
#define PPCAT_NX(A, B) A ## B

// Concatenate preprocessor tokens A and B after macro-expanding them.
#define PPCAT(A, B) PPCAT_NX(A, B)

// Turn A into a string literal without expanding macro definitions (however, if invoked from a macro, macro arguments are expanded).
#define STRINGIZE_NX(A) #A

// Turn A into a string literal after macro-expanding it.
#define STR(A) STRINGIZE_NX(A)


#define COMPLEX_DEPOSITION

#ifdef COMPLEX_DEPOSITION
#define CD "_COMPDEP"
#else
#define CD ""
#endif


#define WIRESLIFETIMES

#ifdef WIRESLIFETIMES
#define GAP 2
#define WLT STR(PPCAT(_WLT:G, GAP))
#define DISABLE_METROPOLIS
#else
#define WLT ""
#endif

#define VERSION VERSIONX CD WLT

which produces V008.1-11-g68a9c89cb4-dirty_COMPDEP_WLT:G2 and I am happy with it.

Must be noted that I changed -DVERSION=... to -DVERSIONX=... inside Makefile

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.