How to concatenate two or more Integers using Macros? - c

If a=1, b=2, c=3... I would like to write a macro which concatenates them like this 123.
But when I try this:
#include<stdio.h>
#define cat(a,b,c) a##b##c
int main()
{
int a=1,b=2,c=3,d;
d=cat(1,2,3); //Works
d=cat(a,b,c); // Returns an error...How to make this work?
return 0;
}

You can't -- the preprocessor has no idea about variables and what values you're going to assign to them when the program runs at some arbitrary time after the preprocessor has finished executing.

hash-define macros are pre-compile time and are preprocessed before compilation. The preprocessor will not have access to variable values. d=cat(a,b,c) will get converted to d=abc by the preprocessor.
You would need to use itoa or something similar and concatenate the resulting strings and then atoi back.
Or just do some arithmetic to figure out the result.

Preprocessor stringifying can't work on variables, it has to take a literal and convert it to a string during processing; the preprocessor deosn't know what a, b, and c equals in your cat() call. You would need to write a macro that actually uses C++ to do the combining. For example:
#define cat(a, b, c, d) \
do { \
std::stringstream ss; \
ss << a << b << c; \
ss >> d; \
} while(0)
(the do/while(0) is a common hack to let you add a semi-colon after the cat call safely)
You won't be able to use a "return value" from this, but you can do:
int a = 1, b = 2, c = 3, d;
cat(a, b, c, d);
// d == 123 now

This might be a starting point:
#include <stdio.h>
#define cat(x,a,b,c) snprintf(x, sizeof(x), "%d%d%d", a, b, c)
main(int argc, char *argv[])
{
char s[20];
cat(s, 4,5,6);
printf("%s\n", s);
}

if it it isnt important that this is done at compile time, you can use something like this:
#include <math.h>
unsigned intcat(unsigned a, unsigned b, unsigned c)
{
unsigned dlogc = 1 + (unsigned)(log(c)/log(10));
unsigned dlogb = 1 + (unsigned)(log(b)/log(10));
return (unsigned)(c + pow(10,dlogc) * b + pow(10,dlogb+dlogc) * a);
}
i dont know if there is anything in the boost libraries to do such math at compile time using TMP.

It is possible for preprocessor defined integers.
The preprocessor needs a call to another function to expand.
You do it as follows:
#define I_BASE_CONCAT(x,y) x ## y
#define I_CONCAT(x,y) I_BASE_CONCAT(x,y)
There it is. Now if you call I_CONCAT it will expand it to x##y, but with the values of x and y.

The C preprocessor does just dummy text substitution at compile time.
What means text substitution? The preprocessor will output C code substituting the parameters of the macro with the passed values. It does not matter if you pass a variable or a constant number, you will just get dummy substitution (also called macro "expansion").
Let's go to see how the preprocessor will "expand" #define cat(a,b,c) a##b##c.
d=cat(1,2,3); expands to: d=123; and this is valid code because you have declared int d.
d=cat(a,b,c); expands to: d=abc; and this will not compile since there's no int abc variable.
What means compile time? It means that this text substitution is done on the source code, and the output disregards the content of the variables passed to the macro. In other words, it does not matters that you have initialized a, b, and c to 1, 2, and 3: the result will be just the concatenation (due to the ## "token-pasting" preprocessor operator) of the passed values. In your case the result is abc, which means nothing in your code.

You could also use this function to concatenate 3 integers
(the other intcat function above does not work when a 0 is the second or third digit. That is because the log of 0 is negative infinity and when you pass 0 it subtracts 1 from your total).
unsigned intcat(unsigned a, unsigned b, unsigned c)
{
uint8_t ax = a;
uint8_t bx = b;
uint8_t cx = c;
ax = (ax * 100);
bx = (bx * 10);
cx = (cx * 1);
return(ax + bx + cx);
}

Related

Difference between Call-by-name and Call-by-macro-expansion

Let's assume we have the following code in a language that looks a lot like C.
int A[2];
A[0]=4;
A[1]=7;
void f(int x, int y) {
x++; A[1]++; y++;
printf(x, y, A[0], A[1]);
}
void main() {
int k = 0;
f(k, A[k]);
print(k, A[0], A[1]);
}
I want to define the output of this program.
I haven't understood well the difference between the call-by-name and the call-by-macro-expansion method.
So, in the call-by-name method, k is initialized to 0 and then f() function is called. x becomes equal to "k" and y becomes equal to "A[k]". The first command in the called function is x++ which increases the value of "k" by 1. So k becomes equal to 1. Then A[1] is increased, so A[1] becomes 7+1=8. None of the x,y are affected. Finally, we have the command y++ which increases the value of "A[k]" by 1, so it increases the value of A[1] (since now k=1) by 1, so A[1] becomes now 8+1=9.
Then f() prints: 1,9,4,9
And then we return to the main() fuction which prints: 1,4,9
So, the output of the program is 1,9,4,9,1,4,9 if I am not mistaken.
But how does call-by-macro-expansion differs from this method? What does it change?
There is nothing like "call-by-macro" in C language. There are only macros which take parameters. Macros are just textually replaced by the preprocessed tokens.
IMO macros should be used only if they are really needed, in most cases it better to use inline functions. Macros are dificult to debus (as compiler compiles the preprocessed .c file) and error prone.
Example
#define SUB(a,b) a-b
and the usage
printf("%d", SUB(3-2,4-5));
the result will not be 2 only -8
But how does call-by-macro-expansion differs from this method? What does it change?
For C, "call-by-macro-expansion" doesn't exist. Instead, for macros the preprocessor does a glorified "cut&paste" operation on raw text.
For example, if you have this:
int A[2];
A[0]=4;
A[1]=7;
#define MACRO(x, y) { \
x++; A[1]++; y++; \
printf(x, y, A[0], A[1]); \
}
void main() {
int k = 0;
MACRO(k, A[k]);
print(k, A[0], A[1]);
}
Then the preprocessor will cut&paste the text from the macro to where the macro is used and then replace x and y with the arguments you provided, so that (after preprocessing) the source code looks like this:
int A[2];
A[0]=4;
A[1]=7;
void main() {
int k = 0;
{ \
k++; A[1]++; A[k]++; \
printf(k, A[k], A[0], A[1]); \
}
print(k, A[0], A[1]);
}
Of course the macros don't need to contain valid code, and the source doesn't even need to be C at all (e.g. you could use the preprocessor to preprocess assembly language source code by telling the compiler "don't compile, just output the preprocessed text"); and there's no real reason why you can't use a completely different preprocessor (with completely different features and/or macro syntax) and feed the resulting text into a C compiler (telling the compiler "don't preprocesses, just compile").
In practice; the main differences for macros and functions are:
for macros, there's no type-checking on the parameters, so bugs end up being more annoying to find
for macros, a debugger will only say the line number where the macro was expanded and won't say where the code actually came from, so bugs end up being more annoying to find
for macros, because they don't have to be valid C you can do some bizarre shenanigans (e.g. #define forever while(1) { so you can use forever i++; } as an infinite loop), and can be powerful for code obfuscation (deliberately making it hard to read the code).
for functions, the compiler can decide not to inline the function to reduce code size
for functions, you can have recursion (with macros you can't - it'd end up being an infinite amount of text)
for functions, you can have function pointers and/or have external functions (where the linker figures out where the function is, either with static linking or dynamic linking).
For a simpler example of (a) difference, consider this code:
#define f(x) { \
x++; \
}
void g(int x) {
x++;
}
void main() {
int a = 1;
int b = 1;
f(a);
printf("%d\n", a);
g(b);
printf("%d\n", b);
}
These look the same, but are not. After expanding the macro and inlining the function, it becomes more like this:
void main() {
int a = 1;
int b = 1;
a++;
printf("%d\n", a); // Will print "2' because the original `a` was changed
int x = b;
x++;
printf("%d\n", b); // Will print "1' because the original `b` was not changed
}
Note that this is exactly the same problem with the example above (for the macro, the x++; modifies the original k and not a copy of the original k; and for the function the x++; modifies a copy and not the original).

Ununderstandable function-like macro in C

i have this c macro code :
#define d(x, y, z) ( \
x += z, \
y += x, \
x += y \
)
I have several questions :
Does this macro function return something ? (e.g. return x, y, or z)
or is it just add the parameter variable with itself ? (which is
useless, i think).
What does the \ means ?
Why does the original coder use comma-operator after each operation ? Why not just use ; instead of , ?
Any help would be appreciated
Does this macro function return something ? (e.g. return x, y, or z) or is it just add the parameter variable with itself ? (which is useless, i think).
It modifies the value of the variables. The "return" value is the final value of x.
What does the \ means ?
When placed last on a line, it negates the newline so that the macro definition can span more than one line.
Why does the original coder use comma-operator after each operation? Why not just use ; instead of `, ?
Macros replace text. Consider the following code:
int x=1, y=2, z=3, f;
f = 3 * (d(x,y,z));
If the macro uses comma, the code becomes:
int x=1, y=2, z=3, f;
f = 3 * (x+=z, y+=x, x+=y); // Evaluates to 3 * (the final value of x)
If the macro uses semicolon, the code becomes:
int x=1, y=2, z=3, f;
f = 3 * (x+=z; y+=x; x+=y); // Syntax error!!!
1) The macro does not return anything itself. It is just a dumb piece of code substituted literally by the preprocessor wherever it encounters it. It can be any kind of text.
2) \ is used for letting the preprocessor know that the current macro also expands over the next line. (multi-line macro)
3) I cannot make any assumption about the original coder's intentions. However by using the comma operator in there the whole macro becomes a C language expression. For example running something like this works (it wouldn't if semicolons were in there):
int a = 0;
int x = 1;
int y = 2;
int z = 3;
a = d(x, y, z);
printf("a = %d\n", a);
printf("x = %d\n", x);
printf("y = %d\n", y);
printf("z = %d\n", z);
and prints:
a = 10
x = 10
y = 6
z = 3
First and foremost #define is a Preprocessor Directive, which means when the source code/c code is complied the #define replaces LHS with RHS - meaning whereever the d(x,y,z) is used will be replaced with the equation given
for example the below c code will print - modified a = 9, b=8, c=9
#define d(x,y,z) \
x+=1, \
y+=2, \
z+=3
#include <stdio.h>
int main()
{
unsigned int a,b,c;
a=5;
b=6;
c=7;
printf("modified a = %d, b=%d, c=%d \n",d(a,b,c));
}
basically what happened here is d(a,b,c) - is replaced with a+=1,b+=2,c+=3
The meaning of \ is that the pre-processor directive continues in the next line.
As for as the comma-operator is concerned we need to look at source code to see where exactly it is used. as you can see in the above code the comma operator actually separates all the three variables and is able to print properly - if in case i replace comma with any other operator we will get compilation error.
Hope this answers your questions :)
Regards
Hari

Simple Macro Causes Compile Error

I'm attempting to define a macro that allows me to pass in 2 numbers as well as an operator. I want the macro to carry out the specified operation on the two numbers and return the result.
My definition is:
#define GENERAL_OP(x,y,op) ((x) op (y))
which works fine when I call
int result = GENERAL_OP(1, 2, -);
but as soon as I try to pass it a character (which is what I actually need to do in my
generalized function that calls the macro) as in the following example:
void Evaluate(char op)...
int result = GENERAL_OP(1, 2, op);
void Evaluate(char op)...
int result = GENERAL_OP(1, 2, op);
Macro replacement is done before compile time, but the argument of Evaluate is only available at runtime, so the macro expansion leads to
int result = ((1) op (2));
there, and op is not a token that can appear there (probably an undeclared identifier).
Preprocessor operates at compile-time, you can't use the value of op inside your macro.
I see what you're going for... it's sort of like trying to unstringify. I'm pretty sure it can't work the way you want it to. Your best bet would be to do something like:
void Evaluate(char op, int x, int y)
{
int result;
if(op == '-')
GENERAL_OP(x, y, -);
...
But that doesn't make it very "general"...

What does #define, EQ(a, b) ((a) == (b)) mean?

I have this been given C code where the heading statement includes the following:
#define, EQ(a, b) ((a) == (b))
What does it mean?
The comma is an error that will prevent the code from compiling: I'll assume that it's a typo.
Given:
#define EQ(a, b) ((a) == (b))
This defines a macro for the equality operator ==.
Using this macro later in the code, you can type, e.g.:
if (EQ(2+2, 4))
instead of:
if (2+2 == 4)
Not very useful, really.
It means nothing: this code is ill-formed. The token immediately following a #define must be an identifier, which , is not.
If the , were to be removed, this would define a function-like macro named EQ that takes two arguments.
Let's take it step by step
#define MAX 10
This will replace every instance of the word "MAX" by 10 in your code file. this is very much like defining a constant variable with one major difference. The interpretation of #define statement is done way before compilation. which helps for an example to use MAX as an array size. Which would have caused a compiler error in many cases if you have used a variable instead.
you can use cpp <filename.c> command in Linux terminal to see what will happen when a macro is executed.
for an example this code:
#define MAX 10
int numbers[MAX];
after preprocessing (i.e. interpretation of the preprocessor macros)
int numbers[10];
note that the #define statement will vanish once interpreted.
This takes us to another example
#define square(x) (x * x)
every instance of square(x) in our code will not only be replaced by (x * x) but also the value of x will be replaced. Which has an effect similar to function deceleration but again it is different
so
square(5) will be replaced by (5 * 5)
Finally our example
#define, EQ(a, b) ((a) == (b))
This will replace every instance of EQ(a, b) by ((a) == (b))
so for an example
EQ(4, 5) will be replaced by ((4) == (5))
Now what does "==" mean? it is the "check if equal" if 4 and 5 are equal the whole expression would evaluate as 1 (which obviously is not true) and thus this expression will end up to be evaluated as 0.
Which more or less like the effect of this function
int EQ(int a, int b)
{
return (a == b);
}
Which could be also written as
int EQ(int a, int b)
{
if (a ==b) return 1;
if (a !=b) return 0;
}
Note that with the macro we avoided two variable declarations and there is no function call really and it is in general quicker. This advantage will be obvious if you have a slower processor (or microprocessor).
Finally let me state the obvious
#define simple_macro 5
int some_integer_variable = 10;
.
.
.
some_integer_variable = simple_macro;
simple_macro = 12; /* illegal statement */
simple_macro++; /* illegal statement */
because after running the preprocessor this will be
int some_integer_variable = 10;
.
.
.
some_integer_variable = 5;
5 = 12;
5 ++;
Oh! I might have talked too much but let me leave you with this (obvious) code
#define MAX 10
int variable = MAX; /*this is a MAX variable */
char some_string[] = "the MAX value"; /* no replacement will happen here */
int variable_MAX; /* no replacement will happen here */
after running the preprocessor will be
int variable = 10;
char some_string[] = "the MAX value";
int variable_MAX;

use of ## and # operator to concatenate the strings in a macro in C

I am having a code which requires to concatenate strings as shown below:
#define CMD(A,B) CMD_##A_PROMPT##B
void main()
{
int a = 10, b = 5;
printf("%s\n", CMD(a, b));
}
the desired output is: CMD10_PROMPT5
Can this be achieved by any means?
I don't think that this can be done, because the macro you're looking for is a compile-time "stringification", an the parameters receive their values at run-time.
If you're looking for run-time "stringification", use sprintf and the like.
You can do it by replacing int a = 10, b = 5; with:
#define a 10
#define b 5
Otherwise it's not possible. C translation occurs in a series of phases defined in the standard, and preprocessing phase occurs before any object definitions are parsed. As far as the preprocessor is concerned, int a = 10 does not establish any relationship between the token a and the token 10.
If all you're after is the output, do it like this:
#define CMD_PATTERN "CMD_%d_PROMPT%d"
int main() {
int a = 10, b = 5;
printf(CMD_PATTERN "\n", a, b);
}
There's unfortunate requirement that the arguments are supplied in the same order that they appear in the pattern - this makes it difficult to change the order in future. For that reason, it might be better to define a formatting function rather than just a pattern.

Resources