C/C++ macro string concatenation
If they're both strings you can just do:
#define STR3 STR1 STR2
This then expands to:
#define STR3 "s" "1"
and in the C language, separating two strings with space as in "s" "1"
is exactly equivalent to having a single string "s1"
.
string concatenation with macro
You need to omit the ##
: adjacent string literals get concatenated automatically, so this macro is going to concatenate the strings the way you want:
#define CONCAT(string) "start"string"end"
For two strings:
#define CONCAT(a, b) (a"" b)
Here is a link to a demo on ideone.
Macro for concatenating two strings in C
Try this
#define space_conc(str1,str2) #str1 " " #str2
The '##' is used to concatenate symbols, not strings. Strings can simply be juxtaposed in C, and the compiler will concatenate them, which is what this macro does. First turns str1 and str2 into strings (let's say "hello" and "world" if you use it like this space_conc(hello, world)
) and places them next to each other with the simple, single-space, string inbetween. That is, the resulting expansion would be interpreted by the compiler like this
"hello" " " "world"
which it'll concatenate to
"hello world"
HTH
Edit
For completeness, the '##' operator in macro expansion is used like this, let's say you have
#define dumb_macro(a,b) a ## b
will result in the following if called as dumb_macro(hello, world)
helloworld
which is not a string, but a symbol and you'll probably end up with an undefined symbol error saying 'helloworld' doesn't exist unless you define it first. This would be legal:
int helloworld;
dumb_macro(hello, world) = 3;
printf ("helloworld = %d\n", helloworld); // <-- would print 'helloworld = 3'
How do I concatenate two string macros in C?
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
Concatenate preprocessor defines to form a string
After more digging, I found that it is indeed possible, and here's how.
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
/* here's the magic */
#define _CONCAT(x,y) x##y
#define CONCAT(x,y) _CONCAT(x,y)
#define VERSION VERSION_MAJOR.CONCAT(VERSION_MINOR,REVISION)
integer version_major = VERSION_MAJOR;
integer version_minor = VERSION_MINOR;
string revision = STRINGIFY(REVISION);
string version_string = STRINGIFY(VERSION);
Like STRINGIFY
, the macro CONCAT
needs to be defined with two levels to make it work.
The output is:
integer version_major = 1;
integer version_minor = 0;
string revision = "b";
string version_string = "1.0b";
as expected.
Macro string concatenation
The macro works only on string literals, i.e. sequence of characters enclosed in double quotes. The reason the macro works is that C++ standard treats adjacent string literals like a single string literal. In other words, there is no difference to the compiler if you write
"Quick" "Brown" "Fox"
or
"QuickBrownFox"
The concatenation is performed at compile time, before your program starts running.
Concatenation of const char*
variables needs to happen at runtime, because character pointers (or any other pointers, for that matter) do not exist until the runtime. That is why you cannot do it with your CONCAT
macro. You can use std::string
for concatenation, though - it is one of the easiest solutions to this problem.
Related Topics
Why Copying Stringstream Is Not Allowed
C++ Std::Set Update Is Tedious: I Can't Change an Element in Place
Accessing Class Members on a Null Pointer
What Are All the Member-Functions Created by Compiler For a Class? Does That Happen All the Time
Catching Exception: Divide by Zero
C++ Static Initialization Order
Why Is the Type of the Main Function in C and C++ Left to the User to Define
Concurrency: Atomic and Volatile in C++11 Memory Model
How to Construct a C++ Fstream from a Posix File Descriptor
Difference Between Static_Cast≪≫ and C Style Casting
What Should Go into an .H File
Is Std::Vector So Much Slower Than Plain Arrays
Why C++ Containers Don't Allow Incomplete Types