KdPrint(("Enter HelloWDMAddDevice\n"));
What's the reason for doing that?
That is so you can pass an entire argument list to the macro and have it pass it on to a function that takes a variable number of arguments.
I would bet anything that the definition of that macro is:
#if DEBUG /* or something like it */
#define KdPrint(args) (printf args)
#else
#define KdPrint(args) /* empty */
#endif
Or similar to some other function that works just like printf.
If it were defined as printf(args), then you could only pass the single string argument, because an argument to a macro can't contain a comma that isn't inside a nested parenthesis.
It causes everything inside the parens to be treated as a single parameter to the macro. In the example shown, it can allow for varargs types of parameters:
KdPrint(( "My info is %s\n", "my name" ));
As well as
KdPrint(( "fn %s ln %s\n", "my", "name" ));
If the macro in question was not well written using parentheses, it might be necessary because of operator precedence. Take this macro for example:
#define MY_MACRO(a) a * 11
Well, if you did this:
int b = MY_MACRO(1 + 2);
b, instead of being 33 like it should, would actually be replaced with int b = 1 + 2 * 11 which is 23 and not 33. If your macro isn't written like that, though (without parenthesis around the a) then it's unnecessary.
If this is the KdPrint() that you are talking about, then this is because you can use KdPrint() macro with format arguments, and it is not a variable length macro.
For example, you can do:
KdPrint(("The answer is %d\n", 42));
and so on.
For your specific example, I cannot tell you, because I don't know what is XdPrint.
But in a more general case, it is because a macro I just like a search and replace. Suppose you have:
#define MULT(a,b) (a*b)
If you call MULT(1+1, 2+2), it would become 1+1*2+2, and result as 5 instead of 8 as you would expect. Doing MULT((1+1), (2+2)) would gives you the expected result. That is why you need to double the brackets.
Related
For example I have a macro:
#define PRINT(int) printf(#int "%d\n",int)
I kinda know what is the result.
But how come #int repersent the whole thing?
I kinda forget this detail. Can anybody kindely give me a hint?
Thanks!
In this context (applied to a parameter reference in a macro definition), the pound sign means to expand this parameter to the literal text of the argument that was passed to the macro.
In this case, if you call PRINT(5) the macro expansion will be printf("5" "%d\n", 5); which will print 5 5; not very useful; however if you call PRINT(5+5) the macro expansion will be printf("5+5" "%d\n", 5+5); which will print 5+5 10, a little less trivial.
This very example is explained in this tutorial on the C preprocessor (which, incidentally, is the first Google hit for c macro pound sign).
"#" can show the name of a variable, it's better to define the macro as this:
#define PRINT(i) printf(#i " = %d\n", i)
and use it like this:
int i = 5;
PRINT(i);
Result shown:
i = 5
That is a bad choice of name for the macro parameter, but harmless (thanks dreamlax).
Basically if i write like so
PRINT(5);
It will be replaced as
printf("5" "%d\n",5);
or
printf("5 %d\n",5);
It is a process called Stringification, #int is replaced with a string consisting of its content, 5 -> "5"
'#' is called a stringize operator.
Stringize operator puts quotes around the parameter passed and returns a string. It is only used in a marco statements that take the arguments.
#include<stdio.h>
#define stringLiteral(sl) #sl
int main()
{
char StringizeOpreator = 'a';
printf(stringLiteral(StringizeOpreator));
return 0;
}
Here the stringLiteral marco takes the formal argument sl and returns #sl. Actual argument passed is StringizeOpreator variable. The return statement #sl has # operator, that puts quotes around the argument like "StringizeOpreator" and returns a string.
So the output of the above program is the name of the actual parameter 'StringizeOpreator' rather than the value stored in the actual parameter passed.
output :
StringizeOperator
...
exitcode 0
To learn more visit this link:
Stringize Operator
Let's say I have already defined 9 macros from
ABC_1 to ABC_9
If there is another macro XYZ(num) whose objective is to call one of the ABC_{i} based on the value of num, what is a good way to do this? i.e. XYZ(num) should call/return ABC_num.
This is what the concatenation operator ## is for:
#define XYZ(num) ABC_ ## num
Arguments to macros that use concatenation (and are used with the operator) are evaluated differently, however (they aren't evaluated before being used with ##, to allow name-pasting, only in the rescan pass), so if the number is stored in a second macro (or the result of any kind of expansion, rather than a plain literal) you'll need another layer of evaluation:
#define XYZ(num) XYZ_(num)
#define XYZ_(num) ABC_ ## num
In the comments you say that num should be a variable, not a constant. The preprocessor builds compile-time expressions, not dynamic ones, so a macro isn't really going to be very useful here.
If you really wanted XYZ to have a macro definition, you could use something like this:
#define XYZ(num) ((int[]){ \
0, ABC_1, ABC_2, ABC_3, ABC_4, ABC_5, ABC_6, ABC_7, ABC_8, ABC_9 \
}[num])
Assuming ABC_{i} are defined as int values (at any rate they must all be the same type - this applies to any method of dynamically selecting one of them), this selects one with a dynamic num by building a temporary array and selecting from it.
This has no obvious advantages over a completely non-macro solution, though. (Even if you wanted to use macro metaprogramming to generate the list of names, you could still do that in a function or array definition.)
Yes, that's possible, using concatenation. For example:
#define FOO(x, y) BAR ##x(y)
#define BAR1(y) "hello " #y
#define BAR2(y) int y()
#define BAR3(y) return y
FOO(2, main)
{
puts(FOO(1, world));
FOO(3, 0);
}
This becomes:
int main()
{
puts("hello " "world");
return 0;
}
I'm working in a C program and I came across a problem. I have this
#define NUMBER_OF_OPTIONS 5
#define NAME_OPTION1 "Partida Rapida"
#define NAME_OPTION2 "Elige Nivel"
#define NAME_OPTION3 "Ranking"
#define NAME_OPTION4 "Creditos"
#define NAME_OPTION5 "Exit"
for (iterator = 1; iterator <= NUMBER_OF_OPTIONS; iterator++){
menu_options[iterator-1]= NAME_OPTION + iterator
}
I want that "NAME_OPTION + iterator" takes the value of the corresponding #define. For example if the variable "iterator" is equal to one, I want menu_options[iterator-1] to take the value of NAME_OPTION1, which is "Partida Rapida".
How can I get this?
Essentially, you can't. #define macros are handled by the C Preprocessor and do textual substitution wherever that macro appears in the code. The macro NAME_OPTION has not been defined, so the compiler should complain. C does not allow appending numbers onto strings, or especially onto symbols like NAME_OPTION. Use an array of const char*, which you can then refer to with your iterator.
You can't use defines as this, you can do:
const char *menu_options[5] = {
"Partida Rapida",
"Elige Nivel",
"Ranking",
"Creditos",
"Exit"
};
If you use #define macro, you just tell preprocessor to replace every occurence of defined word by something else before the code is compiled into machine code.
In this case NUMBER_OF_OPTIONS will be replaced by 5, but there's no occurence of NAME_OPTION*, so nothing will be replaced and you'll probably get an error while preprocessing.
Piere's solutions shows how to do it, but I highly doubt that there's an iterator over char *array, so you have to iterate over given array using an integer index.
For example I have a macro:
#define PRINT(int) printf(#int "%d\n",int)
I kinda know what is the result.
But how come #int repersent the whole thing?
I kinda forget this detail. Can anybody kindely give me a hint?
Thanks!
In this context (applied to a parameter reference in a macro definition), the pound sign means to expand this parameter to the literal text of the argument that was passed to the macro.
In this case, if you call PRINT(5) the macro expansion will be printf("5" "%d\n", 5); which will print 5 5; not very useful; however if you call PRINT(5+5) the macro expansion will be printf("5+5" "%d\n", 5+5); which will print 5+5 10, a little less trivial.
This very example is explained in this tutorial on the C preprocessor (which, incidentally, is the first Google hit for c macro pound sign).
"#" can show the name of a variable, it's better to define the macro as this:
#define PRINT(i) printf(#i " = %d\n", i)
and use it like this:
int i = 5;
PRINT(i);
Result shown:
i = 5
That is a bad choice of name for the macro parameter, but harmless (thanks dreamlax).
Basically if i write like so
PRINT(5);
It will be replaced as
printf("5" "%d\n",5);
or
printf("5 %d\n",5);
It is a process called Stringification, #int is replaced with a string consisting of its content, 5 -> "5"
'#' is called a stringize operator.
Stringize operator puts quotes around the parameter passed and returns a string. It is only used in a marco statements that take the arguments.
#include<stdio.h>
#define stringLiteral(sl) #sl
int main()
{
char StringizeOpreator = 'a';
printf(stringLiteral(StringizeOpreator));
return 0;
}
Here the stringLiteral marco takes the formal argument sl and returns #sl. Actual argument passed is StringizeOpreator variable. The return statement #sl has # operator, that puts quotes around the argument like "StringizeOpreator" and returns a string.
So the output of the above program is the name of the actual parameter 'StringizeOpreator' rather than the value stored in the actual parameter passed.
output :
StringizeOperator
...
exitcode 0
To learn more visit this link:
Stringize Operator
I am trying to solve two Preprocessor related questions but in both programs I am getting results that I am not able to figure out how. Below is my program:
#include<stdio.h>
#define SQUARE(x) x*x
int main()
{
float s=10,u=30 ,t=2,a;
a=2*(s-u*t)/SQUARE(t);
printf("Result:%f\n",a);
return 0;
}
According to me, the output of this programme should be -25.000 but I am getting -100.000.
And in second program:
#define FUN(i,j) i##j
int main()
{
int val1 = 10;
int val12 = 20;
clrscr();
printf("%d\n",FUN(val1,2));
getch();
}
Output should be 102 but I am getting 20;
why is it so?
#define SQUARE(x) x*x
should be
#define SQUARE(x) ((x)*(x))
Indeed, without the parentheses, 2*(s-u*t)/SQUARE(t) is expanded as
2*(s-u*t)/t*t
which is interpreted as
(2*(s-u*t)/t)*t
As to your second problem, FUN(val1,2) will get expanded as val12 per the semantics of the ## operator. It is still not clear what your intent is: the printf line will be understood as
printf("%d\n", val12);
which will print 20.
the first one:
a=2*(s-u*t)/SQUARE(t);
after replacing the define we get:
a=2*(s-u*t)/t*t;
now, since we don't have () in the definition of SQUARE we get:
a=2*(10-30*2)/2*2; --> a=2*(-50)/2*2; --> a=-100/2*2; --> a=-50*2; --> a=-100
if you want to get -25 you should define SQUARE(x) as (x*x).
Edit : add explanation regarding the second example.
printf("%d\n"FUN(val1,2));
once again, we first should replace the define (reminder: ## "concatenates" the string of the define - I can't find the perfect words in order to explain it so just take a look at the example...):
printf("%d\n",val12); [note: the comma (,) is missing - so it won't compile.]
since the value of val12 is 20 that's what you'll get.
the point of those 2 examples is to remember that we should always deal with the defines first (since in "real life" the compiler (or pre-processor) does it before the run time)
I hope it helps..
For the first case,
a=2*(s-u*t)/SQUARE(t);
would translate to
a=2*(s-u*t)/t*t;
at compile time. This is a common mistake made with preprocessors.
i know i am late, but i am having the perfect answer.
in c # at define is used to call the text as it is in the function parameter,
example, #define hai(s1) printf("%s=%s",#s1,s1);
in main: i am calling as hai(tom); tom was initialized as "india" string.
the output for this is tom=india, the calling string tom is printed by help of #.
similarly ## is used to take the text from function argument and join them and return the value of the joined identifier.
the above program has two argument va1 and 2. passed to i and j. then va1 and 2 is joined. and form va12.
va12 is the identifier available with value 20. that's why 20 is returned.