I have a set of predefined macros (That I cannot change) where each one takes as input the index for an array. I want to create another macro to be able to choose which previously defined macro to use by pasting the tokens together.
I have tried creating a macro that takes in 2 arguments: x, which picks which previously defined macro to use, and ind, which is passed on to the selected macro.
The code below is ran using
https://www.onlinegdb.com/online_c_compiler
so I can figure out the basic code before I put it into a rather large application.
#include <stdio.h>
//struct creation
struct mystruct {
int x;
int y;
};
//create array of structs
struct mystruct sArr1[2] = {{1,2},{3,4}};
struct mystruct sArr2[2] = {{5,6},{7,8}};
//define macros
#define MAC1(ind) (sArr1[ind].x)
#define MAC2(ind) (sArr2[ind].y)
// Cannot change anything above this //
//my attempt at 2 input macro
#define MYARR(x,ind) MAC ## x ## (ind)
int main() {
printf("%d\n", MYARR(1, 0));
return 0;
}
I want the result to print out the x value of sArr1 at index 0, which is 1. Instead, I get this output
main.c: In function ‘main’:
main.c:29:22: error: pasting "MAC1" and "(" does not give a valid preprocessing token
#define MYARR(x,ind) MAC ## x ## (ind)
^
main.c:33:19: note: in expansion of macro ‘MYARR’
printf("%d\n", MYARR(1, 0));
line 29 should be :
#define MYARR(x,ind) MAC##x(ind)
I tested it. It printed '1', which is what you want.
Related
This questions is about my homework.
This topic is need to use like:
#define GENERIC_MAX(type)\
type type##_max(type x, type y)\
{\
return x > y ? x : y;\
}
The content of the question is to make this code run normally:
#include <stdio.h>
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
The result of the operation is like this:
i=5.2000
j=3
And this code is my current progress, but there are have problems:
#include <stdio.h>
#define printname(n) printf(#n);
#define GenerateShowValueFunc(type)\
type showValue_##type(type x)\
{\
printname(x);\
printf("=%d\n", x);\
return 0;\
}
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
I don’t know how to make the output change with the type, and I don’t know how to display the name of the variable. OAO
This original task description:
Please refer to ShowValue.c below:
#include <stdio.h>
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
Through [GenerateShowValueFunc(double)] and [GenerateShowValueFunc(int)] these two lines macro call, can help us to generated as [showValue_double( double )] and [showValue_int( int )] function, And in main() function called. The execution result of this program is as follows:
i=5.2000
j=3
Please insert the code that defines GenerateShowValueFunc macro into the appropriate place in the ShowValue.c program, so that this program can compile and run smoothly.
A quick & dirty solution would be:
type showValue_##type(type x)\
{\
const char* double_fmt = "=%f\n";\
const char* int_fmt = "=%d\n";\
printname(x);\
printf(type##_fmt, x);\
return 0;\
}
The compiler will optimize out the variable that isn't used, so it won't affect performance. But it might yield warnings "variable not used". You can add null statements like (void)double_fmt; to silence it.
Anyway, this is all very brittle and bug-prone, it was never recommended practice to write macros like these. And it is not how you do generic programming in modern C. You can teach your teacher how, by showing them the following example:
#include <stdio.h>
void double_show (double d)
{
printf("%f\n", d);
}
void int_show (int i)
{
printf("%d\n", i);
}
#define show(x) _Generic((x),\
double: double_show, \
int: int_show) (x) // the x here is the parameter passed to the function
int main()
{
double i = 5.2;
int j = 3;
show(i);
show(j);
}
This uses the modern C11/C17 standard _Generic keyword, which can check for types at compile-time. The macro picks the appropriate function to call and it is type safe. The caller doesn't need to worry which "show" function to call nor that they pass the correct type.
Without changing the shown C-code (i.e. only doing macros), which I consider a requirement, the following code has the required output:
#include <stdio.h>
#define showValue_double(input) \
showValueFunc_double(#input"=%.4f\n" , input)
#define showValue_int(input) \
showValueFunc_int(#input"=%d\n" , input)
#define GenerateShowValueFunc(type) \
void showValueFunc_##type(const char format[], type input)\
{\
printf(format, input); \
}
/* ... macro magic above; */
/* unchangeable code below ... */
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
Output:
i=5.2000
j=3
Note that I created something of a lookup-table for type-specific format specifiers. I.e. for each type to be supported you need to add a macro #define showValue_ .... This is also needed to get the name of the variable into the output.
This uses the fact that two "strings" are concatenated by C compilers, i.e. "A""B" is the same as "AB". Where "A" is the result of #input.
The rest, i.e. the required function definition is very similar to the teacher-provided example, using the ## operator.
Note, this is if the variable name has to correctly be mentioned in the output.
With out the i = things would be easier and would more elegantly use the generated functions WITHOUT having the called showValue_double(i); be explicit macros. I.e. the functions generated are 1:1 what is called from main(). I think that might be what is really asked. Let me know if you want that version.
#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;
The above line is take from Unreal 4, and I know I could ask it over on the unreal forums, but I think this is a general C++ question that warrants being asked here.
I understand the first line defines a macro, however I am not well versed in preprocessor shenanigans in C++ and so I'm lost over there. Logic tells me the backslash means the declaration continues onto the next line.
FThreadSafeStaticStat looks a bit like a template, but there's #'s going on in there and a syntax I've never seen before in C++
Could someone tell me what this means? I understand that you may not have access to Unreal 4, but it's just the syntax I don't understand.
## is the preprocessor operator for concatenation.
So if you use
DEFINE_STAT(foo)
anywhere in the code, it gets replaced with
struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;
before your code is compiled.
Here is another example from a blog post of mine to explain this further.
#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m ## s ## u ## t
#define begin decode(a,n,i,m,a,t,e)
int begin()
{
printf("Stumped?\n");
}
This program would compile and execute successfully, and produce the following output:
Stumped?
When the preprocessor is invoked on this code,
begin is replaced with decode(a,n,i,m,a,t,e)
decode(a,n,i,m,a,t,e) is replaced with m ## a ## i ## n
m ## a ## i ## n is replaced with main
Thus effectively, begin() is replaced with main().
TLDR; ## is for concatenation and # is for stringification (from cppreference).
The ## concatenates successive identifiers and it is useful when you want to pass a function as a parameter. Here is an example where foo accepts a function argument as its 1st argument and the operators a and b as the 2nd and 3rd arguments:
#include <stdio.h>
enum {my_sum=1, my_minus=2};
#define foo(which, a, b) which##x(a, b)
#define my_sumx(a, b) (a+b)
#define my_minusx(a, b) (a-b)
int main(int argc, char **argv) {
int a = 2;
int b = 3;
printf("%d+%d=%d\n", a, b, foo(my_sum, a, b)); // 2+3=5
printf("%d-%d=%d\n", a, b, foo(my_minus, a, b)); // 2-3=-1
return 0;
}
The # concatenates the parameter and encloses the output in quotes. The example is:
#include <stdio.h>
#define bar(...) puts(#__VA_ARGS__)
int main(int argc, char **argv) {
bar(1, "x", int); // 1, "x", int
return 0;
}
Is there a way to "generate" a function name by using the operator ## and a variable value. For example:
#define FUN_I(fun, fun_id) fun##fun_id
#define FUN(fun, fun_id) RECV_CB_FUN_I(fun, fun_id)
int foo0(int x) {
// do something
}
int main()
{
int i = 0;
FUN(foo,i)(1);
}
Macro FUN generates fooi. Is there a way to get foo0 somehow, or I have to use the actual number 0 in this case, e.g FUN(foo, 0)(1);
Cheers
You have to use actual 0 (or another macro). Macro expansion is handled by the C pre-processor at compile time. It knows nothing about runtime values of variables.
As stated, the macro expansion is done at compile time, so the function name wouldn't be know at run time.
It is more appropriate to use function pointers and an array to them.
Example:
typedef int (*TFoo)(int);
int foo1(int x)
{
printf("from foo1: x = %d\n", x);
return 0;
}
int foo2(int x)
{
printf("from foo2: x = %d\n", x);
return 0;
}
TFoo foos[2] = {foo1, foo2};
#define foo(i, x) foos[i](x)
That's that. Hope it helps
'c' preprocessing is a process of replacing macros with the text from their definitions. some operations like ## allow to add its argument as text into definitions. So, everything is done even before compilation starts.
As a result, in your case FUN(fun,i) will be substituted as text and form funi. The only limited way to build function names like you want is to use actual text values or other macros. Here are 2 examples which will work with pre-processing:
FUN(fun, 0)(1);
or
#define I 0
FUN(fun, I)(1);
In the last case I is a macro itself, therefore it also works. (it is always a good idea to name macro name in upper case letters).
I'm aware of multiple Q&As [1, 2]that touch closely on this subject, and I've tried to implement their solutions but the fact that I need to use the . in my concatenation seems to be causing me trouble.
This is what I want:
#include <stdio.h>
#define PROPERTY .value1
#define MAKE_PROP(var) var##PROPERTY
typedef struct {
int value1;
int value2;
} Node;
int main(void) {
Node node;
node.value1 = 1;
node.value2 = 2;
// MAKE_PROP(node) should evaluate to "node.value1".
printf("%d", MAKE_PROP(node));
return 0;
}
However it's giving me all sorts of errors. If I try the PASTER-EVALUATE idea from [2] then it tells me "pasting "." and "PROPERTY" does not give a valid preprocessing token".
Anyone know how to accomplish what I need? It's essential that it stays general and that I can use the var as this is something I'd like to call multiple times on different variable names.
It's not working for two reasons:
The token concatenation operator suppresses the expansion of macros that are used as its operands. So you get nodePROPERTY. The solution to that is to add a level of indirection:
#define PROPERTY .value1
#define CONCAT(a, b) a##b
#define MAKE_PROP(var) CONCAT(var, PROPERTY)
Now PROPERTY is expanded before being fed as an argument to CONCAT.
The result of concatenating tokens must be a single valid token, but node.value1 is 3 tokens (node, . and value1).
Now, it just so happens that you don't need concatenation at all, you just need to build the expression (node .value1) which can be done with following simple macros1:
#define PROPERTY value1
#define MAKE_PROP(var) ( (var).PROPERTY )
1: simplified with the help of Lundin.
Yesterday I tried to optimize my code using macro, but it doesn't compile in some sentences. For simplification, I writed codes below to describe what I want to work out:
#define MACRO(x, y) ((x) + (y))
#define X 2,3
int fun(x, y)
{
return x+y;
}
int main(void)
{
int res;
res = fun(X); //ok
res = MACRO(X); //**error:macro "MACRO" requires 2 arguments, but only 1 given**
printf("%d\n", res);
return 0;
}
I used to believe that macros simply replace words so it's no problem to do this, but now I think I was wrong. :(
More accurately: I was tring to do something like:
//global.h
#define MACRO(brief, num) fun(__LINE__, brief, num)
//test.c
#include <global.h>
#define X "brief",3
void fun(int line_num, char* brief, int num)
{
printf("%d, %s,%d\n", line_num, brief, num); //do something
}
int main(void)
{
fun(__LINE__, X); //ok
MACRO("brief",3); //ok
MACRO(X); //error: macro "MACRO" requires 2 arguments, but only 1 given
return 0;
}
So I need to use this type of macro to reduce args.
I searched everywhere yesterday but nothing was found, I hope I could receive answers here. Thanks a lot. :)
(My English is not very good, I wish I had a clear description of my problem.)
You can use the variable arguments facility of the preprocessor, as in the following example (available on IdeOne):
#include <stdio.h>
#define MACRO(...) MACRO_IMPLEMENTATION(__VA_ARGS__)
#define MACRO_IMPLEMENTATION(x,y) ((x)+(y))
#define X 2,3
int main (void) {
printf ("MACRO (X) = %d\n", MACRO (X));
printf ("MACRO (2,3) = %d\n", MACRO (2,3));
return 0;
}
The output is
MACRO (X) = 5
MACRO (2,3) = 5
The definition of MACRO takes a variable number or arguments, which are bound to __VA_ARGS__ (see section 6.10.3 in the standard). The definition of MACRO calls MACRO_IMPLEMENTATION which now sees two arguments either because MACRO was called with two or because it was called with an argument which expands to a list of two arguments.