There is one function defined in two different ways, one using #define and other using a function. But for the output I am getting different values.
The output is coming out to be 3 -1.
I want to know why using F(x,y) results in different values.
#include<iostream>
#define F(x,y) y-x
using namespace std;
int F2(int x,int y)
{
return y-x;
}
int main()
{
int x=1,y=2, h=2;
cout << F(x+h,y) << " " << F2(x+h,y) << endl;
return 0;
}
First off, you didn't #define a function but a macro. Macros do straight text replacement so the output line is equivalent to:
cout << y-x+h << " " << F2(x+h,y) << endl;
Can you spot the error now?
Classic problem using #define, and one of the main reasons why macros are discouraged. Keep in mind that a macro is little more than a literal substitution, and consider what it expands to:
cout << y-x+h << " " << F2(x+h,y) << endl;
And y-x+h is something very different from y-(x+h).
Always parenthesize uses of macro arguments:
#define F(x,y) ((y)-(x))
#define is a macro directive, not a function. It is just replacing it's occurrences by the macro body. If you do so, you will see that F(x+h,y) is replaced by y-x+h, which is obviously not what you want. The rule for macros is to take all of the parameters and subexpressions into brackes like this:
#define F(x,y) ((y)-(x))
in order to get the correct results.
This way F(x+h,y) will be replaced by ((y)-(x+h)), which is correct
Related
The following preprocessor-based identifier-to-string lookup table:
#include <iostream>
// included generated file
#define KEY_a valueA
#define KEY_b valueB
///////
#define LOOKUP_(_key_) KEY_ ## _key_
#define QUOTE_(_str_) #_str_
#define EXPAND_AND_QUOTE_(_str_) QUOTE_(_str_)
#define LOOKUP(_key_) EXPAND_AND_QUOTE_(LOOKUP_(_key_))
int main() {
std::cout << LOOKUP(a) << std::endl;
std::cout << LOOKUP(b) << std::endl;
std::cout << LOOKUP(c) << std::endl;
}
Output:
valueA
valueB
KEY_c
The first #defines come from an #included header generated by an external script before the compilation.
The LOOKUP macro correctly handles existing key in the table, and substitutes the given value as string literal.
But for non-existing keys, it substitutes the key as string literal.
Is there a way to instead make it substitute a given constant for non-existing keys, without causing a compile-time error, and all within the preprocessing stage?
So for example, the LOOKUP(c) and LOOKUP(whatever) should all be substituted to "undefined", without c or whatever occuring in the included generated file.
The names of the keys should not be outputted to the compiled binary, so ideally they should never be seen by the compiler.
Here's a simple, if hacky, solution. By making the definition of KEY_x a list of two elements (the first of which will be ignored), it permits adding a default value:
#include <iostream>
// included generated file
#define KEY_a _,valueA
#define KEY_b _,valueB
///////
#define LOOKUP_(key) KEY_ ## key
#define QUOTE_(_,str,...) #str
#define EXPAND_AND_QUOTE_(...) QUOTE_(__VA_ARGS__)
#define LOOKUP(key) EXPAND_AND_QUOTE_(LOOKUP_(key),undefined)
int main() {
std::cout << LOOKUP(a) << std::endl;
std::cout << LOOKUP(b) << std::endl;
std::cout << LOOKUP(c) << std::endl;
}
Test on coliru
How to get the macro name inside a macro?
Say we have:
#include <iostream>
using std::cout;
using std::endl;
#define MACRO() \
cout << __MACRO_NAME__ << endl
int main () {
MACRO();
return 0;
}
Expected output:
MACRO
Did little bit of research and I don't think that is doable in c++.
But you could use this:
#define MACRO2(x) cout << #x << endl
#define MACRO MACRO2(MACRO)
In this you can use MACRO2 to do the task of MACRO and you can also access name of MACRO as an argument x.
I am trying to achieve the following but in a way that follows the c++ standard :
#include <iostream>
using namespace std;
#define MAKE_BOTH(MAKE_FUNC) \
MAKE_FUNC(FIRST) \
MAKE_FUNC(SECOND) \
MAKE_FUNC(THIRD) \
MAKE_FUNC(FOURTH)
#define MAKE_STRINGS(NAME) #NAME,
const char* genericString[] {
MAKE_BOTH(MAKE_STRINGS)
};
#define MAKE_ENUM(NAME) NAME = (1L << __COUNTER__),
enum genericEnum {
MAKE_BOTH(MAKE_ENUM)
};
int main()
{
cout << FIRST << endl;
cout << SECOND << endl;
cout << THIRD << endl;
cout << FOURTH << endl;
}
If you think a while about this code, this creates both, enums and array of "strings" which consists of the same names as enums. The examle code expands to :
const char* genericString[] {
"FIRST",
"SECOND",
"THIRD",
"FOURTH"
};
enum genericEnum {
FIRST = 1L << 0; (1)
SECOND = 1L << 1; (2)
THIRD = 1L << 2; (4)
FOURTH = 1L << 3; (8)
};
Basically the enums are assigned power of 2 values, the question is - is there a relatively simple way of achieving the same thing without using COUNTER ?
The problem is similar to this one:
Counting preprocessor macros
but I have to increase the value of counter each time the macro is used at compile time, I could not figure out how to do it without using the non-standard COUNTER macro.
Please beware the c++ 11 is not an option, but using boost is, I tried the boost approach as well but it is not possible to call the #include directive by a macro which unables me from incrementing the boost preprocessor counter.
You may generate something like this:
enum genericEnum
{
MY_ENUM_BASE=0,
FIRST,
PAST_FIRST= (FIRST<<1)-1,
SECOND,
PAST_SECOND= (SECOND<<1)-1,
THIRD,
PAST_THIRD= (THIRD<<1)-1,
FOURTH,
PAST_FOURTH= (FOURTH<<1)-1,
};
using standard macroprocessor without using COUNTER,
i.e. defining MAKE_ENUM as
#define MAKE_ENUM(NAME) NAME, PAST##_NAME= (NAME<<1)-1,
I'm writing a logging class at the moment. The Logger works with streams and also prints the object which is logging at the moment. Here is the macro:
#define OBJLOG(DL, what) DL <= this->Logger->getDebugLevel() ? *this->Logger << DL << "[" << this->Name << "]: "<< what << std::endl : this->Logger->doNothing();
The pseudo code Variant for better overview:
#define OBJLOG(debuglevel, what) debuglevel <= logger.debuglevel ? logger.log(what) : logger.doNothing()
Is there any way to get around the doNothing function call, like doing nothing at all?
#define OBJLOG(DL, what) do { if(DL <= this->Logger->getDebugLevel()) *this->Logger << DL << "[" << this->Name << "]: "<< what << std::endl; } while(0)
See Why use apparently meaningless do-while and if-else statements in macros? for an explanation. (The do {} while(0) isn't strictly necessary here, but I would prefer not to leak an ostream.)
Also, you should always wrap macro argument uses in parentheses, like:
#define OBJLOG(DL, what) do { if((DL) <= this->Logger->getDebugLevel()) *this->Logger << (DL) << "[" << this->Name << "]: "<< (what) << std::endl; } while(0)
Finally, you should move this code into a function and call that in your macro (if you really insist on using a macro) to avoid evaluating your macro arguments more than once.
Have your logger.log() function return a boolean.
Connect your predicates with an and like this: debuglevel <= logger.debuglevel && logger.log
That should do the trick.
If you want an expression that does nothing, try (void)0.
The problem I have is illustrated in the following code.
#include <iostream>
#define X 4
int main()
{
std::cout << "should be 4: " << X << std::endl;
#define Y X + 4
std::cout << "should be 8: " << Y << std::endl;
#undef Y
#define Y X+0
#undef X
#define X Y+1
std::cout << "expecting 5: " << X << std::endl;
}
The error:
test2.cc: In function ‘int main()’:
test2.cc:17: error: ‘X’ was not declared in this scope
The pattern I am trying to emulate is extending a program at code/build level(much like how nginx modules are wired up at compile-time). I need to build up an extensible compile time structure, which is extensible(plugable) by adding #includes to my build, that results in a boost-mpl-vector with a unique name that contains all of my plugins. So if X is the unique end name, X_0, X_1, X_2 are the names that are built up along the way as the vector has mpl-vector push_back applied to it.
I KNOW the abstractions of boost::preprocessor are key, but I don't want to commit the time to researching it just yet, as I'm prototyping part of the system that will eventually be compile-time modularized.
So, for future reference,
Why am I getting an error above ?
What should the correct raw preprocessor pattern look like.
What does the correct boost-preprocessor-library pattern look like.
compiling with g++ -E gives this:
int main()
{
std::cout << "should be 4: " << 4 << std::endl;
std::cout << "should be 8: " << 4 + 4 << std::endl;
std::cout << "expecting 5: " << X+0 +1 << std::endl;
}
So you can see why you get the error.
Why not kill two birds with one stone and use namespaces.
// a.hpp:
namespace a {
const int module_id = 0;
class module_a : extension_module< module_id > { … };
}
#undef last_module
#define last_module a
// b.hpp:
namespace b {
const int last = last_module::module_id + 1;
class module_b : extension_module< module_id > { … };
}
#undef last_module
#define last_module b
This is way less "clever," and leaves a trail of ID's.
However, the modules do need to be included in the same order every time for the ODR to work.
I do not advocate killing any birds.
The problem of your code sample is that you have circular dependency in X and Y macros:
Y is defined as X+0 and X is defined as Y+1. So when macros are expanded (that happens at the point where you use X) you have a problem.
ADD:
It seems that behaviour is this: when expanding macro X inside its definition name X is not defined in preprocessor name space so you see X+0+1 as X expansion.