functional bind operation in C preprocessor - c++

I have a macro like this (it's coming from an actual useful use case, but I've been playing with simplified cases):
#define MY_MACRO(M) M(3) M(5) M(7)
#define MULTIPLY_BY_2(A) (2*A)
I can then write
MY_MACRO(MULTIPLY_BY_2)
// -> (2*3) (2*5) (2*7)
Cool! What I want is this:
#define MULTIPLY(A,B) (A*B)
MY_MACRO(BIND(MULTIPLY, 2))
To get the same result as above. What could BIND be? I've tried some hacks, and can report that this IS almost possible (which I find amazing). But it's not pretty, and not general. Can this be done well? (I.e. build some real functional facilities purely in CPP?) Can it be done well enough to bind a bound macro?
Perhaps what I'm really asking is whether there are tools like this in any preprocessor libraries that you are aware of? I didn't find anything quite like this in Boost.

You can't ask macro programming to be pretty, sorry.

Unbalanced parentheses can do a sort of bind operation, but then the call syntax is different from a normal macro. It needs an extra close paren.
#define BIND( op, arg ) op ( arg,
#define MULTIPLY( a, b ) ( (a) * (b) )
#define MULTIPLY_BY_2 BIND( MULTIPLY, 2 )
MULTIPLY_BY_2( 5 )) // note two close parens
http://ideone.com/EQvs2
You can try defining more macros to generate the close paren as appropriate, but there is probably a better solution.

I am not sure that I completely understand what kind of functionality you want to achieve, but the following suits your example:
#define MULTIPLY_2(X) (2*(X))
#define POW_2(X) ((X)*(X))
#define BIND(OP, NUM) OP ## _ ## NUM
for MULTIPLY_2 & Co watch that you always put parenthesis around the argument to be sure that this has the evaluation order that you want. And also beware that with you general strategy arguments may be evaluated several times, which can be a serious bug if the expression contains side effects.
Better would be to have your basic operations as inline functions and compose the function call with the macros
#define MULTIPLY_2(X) multiply2(X)
#define POW_2(X) pow2(X)

Actually, yes. In the Order library, you could express the above like this:
#include <order/interpreter.h>
#define ORDER_PP_DEF_8my_mac ORDER_PP_FN( \
8fn(8M, 8seq(8ap(8M, 3), 8ap(8M, 5), 8ap(8M, 7))) )
#define ORDER_PP_DEF_8bind ORDER_PP_FN( \
8fn(8F, 8A, 8fn(8X, 8ap(8F, 8A, 8X)) ) )
#define ORDER_PP_DEF_8multiply ORDER_PP_FN( \
8fn(8L, 8R, 8times(8L, 8R)) ) // (already built-in as 8times)
ORDER_PP (
8my_mac(8bind(8multiply, 2)) // -> (6)(10)(14)
)
That's with a manual definition of bind and multiply; Order also supports ML-style partial evaluation natively, so you could just write:
ORDER_PP ( 8my_mac(8times(2)) ) // -> (6)(10)(14)
Aside from the slightly weird syntax imposed by the C preprocessor, the language is basically a fairly straightforward Lisp/ML hybrid with support for many common functional idioms.

Related

Macro with run time argument-change giving wrong ans in cpp [duplicate]

When is it is necessary to put the whole (right) expression of a define macro in parenthesis?
If I do something like
#define SUM(x, y) ((x)+(y))
I have to put the right expression into parenthesis, because "+" has a low precedence in C (and it wouldn't work if I would use it in the following context SUM(x, y) * 5U)
Are these parenthesis still required if I use an operator of the highest precedence e.g.
#define F foo()
or even
#define ACCESS(x, y) (x)->(y)
Does an expression exist that that would break the actual meaning as it would do for the SUM() example?)
For the precedence rules I used http://en.cppreference.com/w/c/language/operator_precedence
It's a good practice to use parenthesis to avoid some big blunders. Currently you might think that your operator is having high precedence but suppose you're making the header file of your code and give it to your friend who uses macro from that file with the function having even higher precedence so at that time it will be a great pain to debug the code. You can save this time as a programmer by putting parenthesis.
Some programmers using simple #defines will write
#define ZERO (0)
which is of no use other than complicating things.
Actually the macro is wysiwyg so with that in mind you can decide what parentheses are needed:
SUM(3,4) => ((3)+(4)) // parentheses around 3 and 4 are not necessary
RATIO(3+4,4+5) => ((3+4)/(4+5)) // probably necessary here due to operator precedence
Its not rocket science to figure this out, it's actually quite straightforward.

Evaluate a Macro Argument Before Processing

I want to be able to generate these options from a macro:
if(void* temp = func(arg)){ foo(temp, variable);return; }
if(void* temp = func2(arg)){ foo(temp, variable2);return; }
if(void* temp = func3(arg)){ foo(temp, variable3);return; }
And so on, but as you can see 1 is the only special case.
I want to write a macro which takes in a number as a parameter and generates a line this code, potentially with numbers far greater than 3. Unfortunately this requires building in the special case if the user passed a 1 and exercising the general case if they passed any other number. Is there a way to do this?
If you really want to use the CPP for this, it's easy enough. An indirect GLUE and an indirect SECOND macro are core tools that you could use:
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(_,X,...) X
The indirect SECOND allows you to pattern match in the preprocessor. The way that works is that you build a first token, which is normally just a throwaway. But since expansion is indirect, if that first token you build is a macro, it will expand first (namely, as part of argument substitution for the variadic). If that expansion contains a comma, it can shift in a "new" second argument right before the indirection picks the second one. You can use that to build your special cases.
Here's a cpp pattern matcher using this construct that returns its argument unless it is 1, in which case it expands to no tokens:
#define NOT_ONE(N) SECOND(GLUE(TEST_IF_1_IS_,N),N)
#define TEST_IF_1_IS_1 ,
Using that, your macro might be:
#define DISPATCH_CASE(N) \
if(void* temp = GLUE(func,NOT_ONE(N))){ \
foo(temp, GLUE(variable,NOT_ONE(N))); \
return;
}
Demo (coliru)
Update: Visual Studio version
But I'm on Visual Studio, and I can't make it work. I think the problem is the __VA_ARGS__ expansion works differently on Visual Studio
For VS, I've found another level of indirection of a particular sort (one that separates the macro from its arguments so the arg list can evaluate in a simple (...) context before it's applied) helps it figure out that commas delimit arguments. Typically I would repeat the same pattern in multiple macros to avoid blue paint.
Here, that translates to the slightly uglier:
#define GLUE(A,B) GLUE_C(GLUE_I,(A,B))
#define GLUE_I(A,B) A##B
#define GLUE_C(A,B) A B
#define SECOND(...) SECOND_C(SECOND_I,(__VA_ARGS__,,))
#define SECOND_I(_,X,...) X
#define SECOND_C(A,B) A B
Demo (goldbolt)

Is it possible to swap the occurences of two variables using macros in C++?

I was working on a contest problem, where I had to initialize a vector in the following way:
vector<pair<int,int>> moves({{i,j}, {i,-j}, {-i,j}, {-i,-j},
{j,i}, {j,-i}, {-j,i}, {-j,-i}});
Although I know that this is not the best way and am aware of a number of different ways to accomplish this with minimal effort, I wonder if there is a way the C++ macros allow me to simply copy-paste the first four elements of the above vector to achieve the same in the following way:
vector<pair<int,int>> moves({{i,j}, {i,-j}, {-i,j}, {-i,-j},
#define i j
#define j i
{i,j}, {i,-j}, {-i,j}, {-i,-j}
#undef i
#undef j
});
The above code obviously does not work because of circular referencing of the variables.
P.S. : Although Matteo Italia's answer is absolutely correct in the above context, I am more interested in knowing whether swapping occurences of variables using macros is possible in C++ or not and how, if possible?
If you really think it's such a saving, you can use a function-style macro and invoke it twice, swapping its arguments.
#define SIGN_COMB(a, b) {(a), (b)}, {(a), -(b)}, {-(a), (b)}, {-(a), -(b)}
vector<pair<int,int>> moves({SIGN_COMB(i, j), SIGN_COMB(j, i)})
The parentheses in the macro expansion as usual are to avoid surprises if expressions are passed as argument (if one passed in e.g. x+y, the negated terms would be -x+y instead if -(x+y)).
Macros are Evil and not a good idea in this context. However, since that appears to be known and the question is more of an academic nature: think "define" rather than "swap". You can use neither "i" nor "j" as a macro's name since you want both to appear in the processed code. So introduce two new identifiers for your macros. Once you update the first four elements to use the new identifiers, you get to copy-and-paste them as requested.
vector<pair<int,int>> moves({
#define a i
#define b j
{a,b}, {a,-b}, {-a,b}, {-a,-b},
#undef a
#undef b
#define a j
#define b i
{a,b}, {a,-b}, {-a,b}, {-a,-b}
#undef a
#undef b
});

Working of pre-processor C++

#define NAME VALUE
I know whenever the compiler see this, it would replace NAME with VALUE. But I'm confused about the working of pre-processing directives such as :
#define CONFIG_VAR(name, type, value)
This does not tell the compiler to replace anything , but I could see statements like
CONFIG_VAR(rank, int, 100)
which would compile successfully. How does this work ?
In your example, that would simply do nothing at all. Any arguments, even those that seem like they should give compilation errors, are accepted and the whole macro call is replaced with an empty string.
If, however, you later replace the definition with something like:
#define CONFIG_VAR(name, type, value) add_config_var<type>(name, value)
it would suddenly do something useful. So, I'd guess that macro is a placeholder for functionality which is not (yet) implemented or not available in that part of the program.
When you say:
#define FOO BAR
what the preprocessor does is to replace each time after this it sees the text FOO by the text BAR, a macro definition. The process is called macro expansion. This is mostly used to define constants, like:
#define N 128
#define MASK (~(1 << 4))
It can be (ab)used to do very funky stuff, as it knows nothing of expressions, statements, or anything. So:
#define CONST (1 + 3 << (x))
is actually OK, and will expand to (1 + 3 << (x)) each time it is seen, using the current value of x each time. Also gunk like:
#define START 5 * (1 +
#define END + 5)
followed by START 2 + 3 + 4 END predictably gives 5 * (1 + 2 + 3 + 4 +5)`
There is also the option of defining macros with parameters, like:
#define BAD_SQUARE(x) x * x
which, if called as BAD_SQUARE(a) will expand to a * a. But BAD_SQUARE(a + b) expands to a + b * a + b, which isn't what was intended (presumably...).
This comes from the dark ages of C, today's C/C++ have safer/cleaner mechanisms to get the same result (use const in C++, in C it sadly defines a variable, not a real constant; use inline functions in C/C++ or templates in C++). There is too much code out there that uses this preprocessor usage (and too many fingers who write this way) so it is practically impossible to get rid of this. As a rule of thumb, learn to read code using macros, whiel learning to write code without them (as far as reasonable, there are times when they come mighty handy...).
This is a macro (more common in C than in C++). According to the definition you provided, the preprocessor will remove occurrences of that "function". A common use-case is usually for logging:
#ifdef DEBUG
#define dprintf(...) printf(...)
#else
#define dprintf(...) // This will remove dprintf lines
#endif
In C++, I believe the general convention is to use inline functions as they provide the same value performance-wise, but are also type checked.
If this really is the entire macro definition, then it simply defines this function-like macro to expand to nothing (an empty string). For example, in the source,
CONFIG_VAR(rank, int, 100);
will be transformed into
;
In this case pre-processor simply removes such strings (replaces with nothing). Widely enough used technique.
Here is example where it is important (actually only one of possible usages):
#if DEBUG_ON
#define LOG(level, string) SomeLogger(level, string)
#else
#define LOG(level, string)
#endif
Probably you should get more familiar with C preprocessor.
There is somewhat close technique (X macro) which builds code which handles repeating lists based on defined actions.

Incrementing Preprocessor Macros

I'm trying to make a simple preprocessor loop. (I realize this is a horrible idea, but oh well.)
// Preprocessor.h
#ifndef PREPROCESSOR_LOOP_ITERATION
#define MAX_LOOP_ITERATION 16 // This can be changed.
#define PREPROCESSOR_LOOP_ITERATION 0
#endif
#if (PREPROCESSOR_LOOP_ITERATION < MAX_LOOP_ITERATION)
#define PREPROCESSOR_LOOP_ITERATION (PREPROCESSOR_LOOP_ITERATION + 1) // Increment PREPROCESSOR_LOOP_ITERATION.
#include "Preprocessor.h"
#endif
The issue is that it doesn't look like PREPROCESSOR_LOOP_ITERATION is being incremented, so it just keeps including itself infinitely. If I change the line to an actual integer (like 17), the preprocessor skips over the #include directive properly.
What am I doing incorrectly?
The "problem" is that macros are lazily evaluated. Consider your macro definition:
#define PREPROCESSOR_LOOP_ITERATION (PREPROCESSOR_LOOP_ITERATION + 1)
This defines a macro named PREPROCESSOR_LOOP_ITERATION and its replacement list is the sequence of five preprocessing tokens (, PREPROCESSOR_LOOP_ITERATION, +, 1, and ). The macro is not expanded in the replacement list when the macro is defined. Macro replacement only takes place when you invoke the macro. Consider a simpler example:
#define A X
#define B A
B // this expands to the token X
#undef A
#define A Y
B // this expands to the token Y
There is an additional rule that if the name of a macro being replaced is encountered in a replacement list, it is not treated as a macro and thus is not replaced (this effectively prohibits recursion during macro replacement). So, in your case, any time you invoke the PREPROCESSOR_LOOP_ITERATION macro, it gets replaced with
( PREPROCESSOR_LOOP_ITERATION + 1 )
then macro replacement stops and preprocessing continues with the next token.
You can perform limited arithmetic with the preprocessor by defining a sequence of macros and making use of the concatenation (##) operator, but it's quite tedious. You should consider using the Boost.Preprocessor library to help you with this. It will work with both C and C++ code. It allows for limited iteration, but what it does allow is extraordinarily useful. The closest feature that matches your use case is likely BOOST_PP_ITERATE. Other facilities like the sequence (BOOST_PP_SEQ) handlers are very helpful for writing generative code.
EDIT: As James pointed out, my original solution did not work due to lazy evaluation of macros. If your compiler supports it, the macro __COUNTER__ increments by one every time it is called, and you can use it to do a simple preprocessor loop like this:
// Preprocessor.h
#define MAX_LOOP_ITERATION 16 // Be careful of off-by-one
// do stuff
#if (__COUNTER__ < MAX_LOOP_ITERATION)
#include "Preprocessor.h"
#endif
I verified this in Visual C by running cl /P Preprocessor.h.
Seriously, find another way to do this.
The preprocessor should be relegated to include guards and simple conditional compilations.
Everything else it was ever useful for has a better way to do it in C++ (inlining, templates and so forth).
The fact that you state I realize this is a horrible idea ... should be a dead giveaway that you should rethink what you're doing :-)
What I would suggest is that you step back and tell us the real problem that you're trying to solve. I suspect that implementing recursive macros isn't the problem, it's a means to solve a problem you're having. Knowing the root problem will open up all sorts of other wondrous possibilities.