Reuse of macro variables - c++

I am trying to benchmark a large number of functions, and I have defined macros to generalise the time stamping. I have made a header file benchmarking.h as follows:
#include <chrono>
#include <iostream>
#define START(x) xstart = std::chrono::steady_clock::now()
#define END(x) xend = std::chrono::steady_clock::now()
#define TIME(x) xtime = std::chrono::duration_cast<std::chrono::nanoseconds>(xend-xstart).count()
#define PRINT(x) std::cout << #x << "(), " << xtime << std::endl
This for all macros, x is substituted with the function name, without parameter brackets. e.g PRINT(foobar); etc.
However, I have used the same macros for multiple function names, as I thought that I could substitute x multiple times.
i.e.
START(foobar);
// later...
START(func);
However, I get an error:
xstart’ has a previous declaration as ‘std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration\<long int, std::ratio<1l, 1000000000l> > > xstart
It seems like I cannot reuse the variable once I have used it to define a function.
However, I never get this error with PRINT. So, is it because I am declaring variables?
I am basically trying to come up with a fast way to timestamp functions, so any other suggestions on how to achieve this quickly are welcome.

You need to use the macro token concatenation operator ##:
#define START(x) x ## start = std::chrono::steady_clock::now()
and similarly for the other macros.
When you just write xstart, the x is not replaced with the macro argument, but xstart is left as is. Argument substitution only operates on single identifiers; they cannot be part of a larger word.

Related

C++ program that use macro [duplicate]

HI ,
Can some one help me in understanding why the value of SQUARE(x) is 49 ?
I am using Visual C++ 6.0 .
#define SQUARE(X) X * X
int main(int argc, char* argv[])
{
int y = 5;
printf("%d\n",SQUARE(++y));
return 0;
}
Neil Butterworth, Mark and Pavel are right.
SQUARE(++y) expands to ++y * ++y, which increments twice the value of y.
Another problem you could encounter: SQUARE(a + b) expands to a + b * a + b which is not (a+b)*(a+b) but a + (b * a) + b. You should take care of adding parentheses around elements when needed while defining macros: #define SQUARE(X) ((X) * (X)) is a bit less risky. (Ian Kemp wrote it first in his comment)
You could instead use an inline template function (no less efficient at runtime) like this one:
template <class T>
inline T square(T value)
{
return value*value;
}
You can check it works:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(no need to write
square<int>(++i)
because the int type is implicit for i)
Because the macro expands to:
++y * ++y
which gives undefined behaviour in C++ - the result could
be anything. This very well known problem should be covered in any decent textbook that covers the use of macros. Which one are you using?
Because macros do textual substitution so the code you wrote gets expanded to
printf("%d\n",++y * ++y );
and then the order of operations is undefined behaviour so this the compiler sees 2 increments and then a multiplication
So be careful with macros better to use functions which as the compiler can expand inline will not take any longer to run.
Secondly don't assume what will happen if you increment and use variables
Macros are not functions: they just alter the text of the program. This operation is called preprocessing and it's automatically executed before your code gets compiled. People write macros to save their time and introduce some variability to their source code.
When you write SQUARE(x), no actual funciton call happens, just the text is modified. The operation is quite dumb, so you have to do additional precautions in cases like yours. Refer to other answers for explanation of your case.

Inverse currying for macros?

Assume we have a #define FOO(x,y) something.
I want to construct such macro #define BAR that BAR(x)(y) would call FOO(x,y). How can I do it, if it's possible at all?
I tried following:
#define BAR(x) FOO(x, BAR_
#define BAR_(y) y)
But got:
error: unterminated argument list invoking macro "FOO"
Here's a MCVE:
#include <iostream>
#define FOO(x,y) std::cout << x << y << '\n';
#define BAR(x) FOO(x, BAR0
#define BAR0(y) y)
#define STR(...) STR0(__VA_ARGS__)
#define STR0(...) #__VA_ARGS__
int main()
{
std::cout << STR( BAR(1)(2) );
}
Another attempt:
#define BAR FOO BAR0
#define BAR0(x) (x, BAR1
#define BAR1(y) y)
This one compiles, but leaves FOO (1, 2) unexpanded in the end.
MCVE:
#include <iostream>
#define FOO(x,y) std::cout << x << y << '\n';
#define BAR FOO BAR0
#define BAR0(x) (x, BAR1
#define BAR1(y) y)
#define STR(...) STR0(__VA_ARGS__)
#define STR0(...) #__VA_ARGS__
int main()
{
// Prints `FOO (1, 2)`, but I want `std::cout << 1 << 2 << '\n';`
std::cout << STR( BAR(1)(2) );
}
1. Dissecting the error
Let's start here:
#define BAR(x) FOO(x, BAR_
#define BAR_(y) y)
#define FOO(x,y) foo{x|y}
BAR(1)(2)
Note that I'm only going to use the preprocessor to debug the preprocessor (why do I need to build C++ programs, which invokes the preprocessor anyway, when I can simply just invoke the preprocessor? (That's rhetorical o/c; I'm just telling a story here)).
Here's how the CPP looks at this. We see BAR; that's a function-like macro. Interesting, but not actionable unless we see an open parentheses. Next, we see... an open parentheses. Now we're getting somewhere... we need to identify its arguments. So we keep scanning: BAR(1)... there... that's the matching open parentheses... looks like we're invoking with one argument. BAR it turns out is defined with one argument, so this works great.
Now we perform argument substitution... so we note that BAR's replacement list mentions its parameter (x) in a non-stringifying, non-pasting way. That means we should evaluate the corresponding argument (1), which is easy... that's just itself. That evaluation result then replaces the parameter in the replacement list, so we have FOO(1, BAR_. We're now done with argument substitution.
The next thing we need to do is rescan and further replacement. So we rescan... FOO, ah, yes. That's a function-like macro... FOO( ...and it's being invoked. Now we're getting somewhere... we need to identify its arguments. So, we keep scanning: FOO(1, BAR_(2)...and, suddenly we reach the end of the file. Huh? That's not right. FOO is being invoked; it's supposed to have a matching parentheses.
You might naively think that BAR_(2) should be invoked, but that's not how macros work. They evaluate outer-in, and the "in" (aka, argument tokens) only evaluates if there's a mention of the parameter in the replacement list, where said mention is not a stringification or paste.
Note that if FOO were not a function-like macro, this story would go an entirely different direction. In such a case, FOO( would simply be tokens the preprocessor doesn't care about... so by the time it sees BAR_(2), it will be invoking a macro. But there's another "cheat"; if FOO is passed over without actually invoking the macro FOO, the tokens would also be skipped over. In both cases, FOO(1, 2) will eventually be produced, which is what you want. But if you then want to evaluate FOO as a function-like macro, you have only one choice. You need a second pass; first pass actually allows your second argument in the sequence to be invoked to build your macro, and this pass must not allow FOO to be invoked. The second pass is needed to invoke it.
2. How to do this
Well, that's easy enough:
#define DELAY()
#define BAR(x) FOO DELAY() (x, BAR_
#define BAR_(y) y)
#define FOO(x,y) foo{x|y}
#define EVAL(...) __VA_ARGS__
BAR(1)(2)
EVAL(BAR(1)(2))
Here's how this is different (first line). After BAR's argument substitution, its replacement list is now FOO DELAY() (1, BAR_ instead of just FOO(1, BAR_. Now, during the rescan, it still sees FOO, which is still interesting... but the next token it sees is DELAY, not an open parentheses. So the CPP in this pass decides it's not invoking FOO and passes on it. After the full DELAY() expansion, which produces nothing, it then just sees (1, BAR_; the first three are just tokens. BAR_, however, is a macro invocation, and so goes the story... so the result of expanding BAR(1)(2) is to produce the tokens FOO(1, 2), error free. But that doesn't evaluate FOO.
The EVAL, however, accepts BAR(1)(2) as an argument. Its replacement list mentions its "parameter" (varying arg variant), so BAR(1)(2) is fully evaluated, producing FOO(1, 2). Then FOO(1, 2) is rescanned, which is when FOO actually gets invoked.

C++ preprocessor conditional parameter

Please note C++03! any C++11 solutions are not good for me, but do post them just for knowledge sake.
I know the preprocessor can do things like:
#define FOO 4
#if FOO == 4
cout<<"hi"<<endl;
#endif
What I need is:
#define BAR(X)\
#if X == 4\
cout<<"hi"<<endl;\
#endif
main.cpp
BAR(4)
I don't see why all the needed information wouldn't be available in preprocessor time.
So, Please tell me how to achieve this kind of behavior.
edit 1:
A normal if condition won't work for my case, because I also do things like:
#define BAR(X)\
#if X == 4\
int poop;
#elif
double poop;
#endif
As you've discovered, you can't do this in the way that you've attempted. Macro expansion simply doesn't have inline conditional evaluation, so you'd have to create multiple macros instead.
However, if you're just trying to "optimise" normal code flow, you can rely on your compiler's optimizations. Consider this:
if (true) {
std::cout << "Hi\n";
}
The resulting program will not have any conditional checks in it, because true is always truthy.
Similarly:
if (false) {
std::cout << "Hi\n";
}
The resulting program will not contain any code to produce output, because false is never truthy.
Similarly:
if (4 != 4) {
std::cout << "Hi\n";
}
The program will still not contain the std::cout code.
In many cases, you may use this fact to keep your code simple and achieve your desired effect:
#define BAR(X) \
if ((X) == 4) {
std::cout << "hi" << std::endl;\
}
The constraint here, of course, is that an if statement must be valid at the place you write BAR(5), or BAR(42) or BAR(999).
This is also flexible in that now you can use a runtime value (like BAR(i)) and, although the conditional can no longer be collapsed at compile-time, in such a case you'd have no reason to expect that anyway.
I take this approach in my logging macro: the macro, when called for LOG_LEVEL_DEBUG, expands to a conditional that is statically known never to match, in release builds.
The idea is to let the compiler do the optimising.
You're also going to want to consider using a little macro expansion trick to avoid problems with subsequent else clauses.
You can do this with the preprocessor if the domain of values for the conditional parameter is well-known (and preferably small). For example, supposing the parameter can only have the values 0 and 1:
#define DOIT_0(X)
#define DOIT_1(X) X
#define CONCAT_(X, Y) X ## Y
#define MAYBE(X) CONCAT_(DOIT_, X)
#define BAR(X) MAYBE(X)( cout<<"hi"<<endl; )
#define YESNO 0
BAR(YESNO)
Live on coliru.
Beware of unprotected commas in the argument to BAR.
For equality checks, again over a small range:
#define CONCAT3_(X,Y,Z) X ## Y ## Z
#define EQUAL_0_0(X) X
#define EQUAL_1_1(X) X
#define EQUAL_1_1(X) X
#define EQUAL_0_1(X)
#define EQUAL_0_2(X)
#define EQUAL_1_0(X)
#define EQUAL_1_2(X)
#define EQUAL_2_0(X)
#define EQUAL_2_1(X)
#define DO_IF_EQUAL(X, Y) CONCAT3_(EQUAL_, X, Y)
#define BAR(X) DO_IF_EQUAL(X, 2) ( std::cout << "hi\n"; )
If you can use Boost, you could do this with Boost.Preprocessor:
#define BAR(X) BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(X, 4), cout << "hi" << endl;)
Some answers here were better than others.
The one I accepted was posted by Christian Kiewiet in a comment, but it was the most accurate for my purpose.
Here is the expanded version:
useCases.h
enum UseCases{
useCase1=0,
useCase2,
useCaseNumber//always last for iterations
}
specializer.h
#include "useCases.h"
<template UseCases theCase>
struct StaticCase{
//empty, thus accidents calling from this can't happen
}
//specialization
template<>
class StaticCase<UseCases::useCase1>{
typedef int T;
static foo(T arg){cout<<"case1";};
}
template<>
class StaticCase<UseCases::useCase2>{
typedef double T;
static foo(){cout<<"case2";};
}
Now, I can do
#define BAR1(useCase) StaticCase<useCase>::foo();
or
#define BAR2(useCase) StaticCase<useCase>::T var;
and the call:
BAR1(UseCases::useCase1)//output - case1
BAR1(UseCases::useCase2)//output - case2

Why can't I add to a ostringstream outside a method/function

If I use this code outside of a method or winmain:
ostringstream vertexid;
vertexid << "bob";
vertexid << " ";
vertexid << " ";
vertexid << 48348093490;
I get all sorts of syntax errors. How does scope play into this why is this happening?
You can do something like this:
std::ostringstream ss;
#define nil(x) ((x), 0)
int x = nil(ss << "Hello");
int y = nil(ss << ", World!");
int z = nil(ss << std::endl);
If you really don't like thinking up variable names, then you can do something even crazier:
#define nilPASTE(x, y) x ## y
#define nilPASTE2(x, y) nilPASTE(x, y)
#define nil2(x) static int nilPASTE2(line_, __LINE__) = nil(x)
nil2(ss << "Goodbye");
nil2(ss << ", Sun!");
nil2(ss << std::endl);
You asked:
How does scope play into this why is this happening?
I assume you mention scope because that is what some error message spat out. But the answer to both parts of that question is that the C++ compiler is following the rules of the C++ language, which does not allow statements to just appear anywhere. They can only appear where they are allowed, which are in functions and method bodies. The reason my technique is allowed is because I am using expressions, and expressions can appear in more places. In particular, they are allowed to appear in an initializer to a variable. And of course, variable declarations are allowed on the outer most level of a translation unit.
All that gobbly gook means: put your statements inside functions and methods.
You can only declare or define stuff at global scope.
The first line alone would be OK (in an implementation file... if in a header, you risk having multiple definitions and would need to declare it as extern instead of defining it), the next lines are just not legal.
At global namespace you cannot have code, because when should it be executed? You can only put executable statements inside functions, for example WinMain/main.
The execution starts at WinMain/main, then you can call your other functions from there.

Problem with Macros

HI ,
Can some one help me in understanding why the value of SQUARE(x) is 49 ?
I am using Visual C++ 6.0 .
#define SQUARE(X) X * X
int main(int argc, char* argv[])
{
int y = 5;
printf("%d\n",SQUARE(++y));
return 0;
}
Neil Butterworth, Mark and Pavel are right.
SQUARE(++y) expands to ++y * ++y, which increments twice the value of y.
Another problem you could encounter: SQUARE(a + b) expands to a + b * a + b which is not (a+b)*(a+b) but a + (b * a) + b. You should take care of adding parentheses around elements when needed while defining macros: #define SQUARE(X) ((X) * (X)) is a bit less risky. (Ian Kemp wrote it first in his comment)
You could instead use an inline template function (no less efficient at runtime) like this one:
template <class T>
inline T square(T value)
{
return value*value;
}
You can check it works:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(no need to write
square<int>(++i)
because the int type is implicit for i)
Because the macro expands to:
++y * ++y
which gives undefined behaviour in C++ - the result could
be anything. This very well known problem should be covered in any decent textbook that covers the use of macros. Which one are you using?
Because macros do textual substitution so the code you wrote gets expanded to
printf("%d\n",++y * ++y );
and then the order of operations is undefined behaviour so this the compiler sees 2 increments and then a multiplication
So be careful with macros better to use functions which as the compiler can expand inline will not take any longer to run.
Secondly don't assume what will happen if you increment and use variables
Macros are not functions: they just alter the text of the program. This operation is called preprocessing and it's automatically executed before your code gets compiled. People write macros to save their time and introduce some variability to their source code.
When you write SQUARE(x), no actual funciton call happens, just the text is modified. The operation is quite dumb, so you have to do additional precautions in cases like yours. Refer to other answers for explanation of your case.