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.
Related
#define prod(a) (a*a)
using namespace std;
int main()
{
int i = 3, j, k, l;
j = prod(i++);
cout << i << endl;
k = prod(++i);
cout << i << endl;
l = prod(i+1);
cout << i << " " << j << " " << k << " " << l;
}
Why is variable "i" incremented twice?
i.e to 5 from 3 after j=prod(i++);
Remember that macros are expanded in the source code, not actually called or evaluated.
That means a "call" like
prod(i++)
results in the expanded code
i++*i++
being seen by the compiler.
Many compilers allow you to stop after preprocessing, or otherwise generate preprocessed source, that you can examine to see macro expansions.
If you continue using such a macro with other expressions as arguments, you will soon see another reason they are bad.
Lets say you use
prod(2+4)
Then that will result in the expansion
2+4*2+4
which is equal to
2+(4*2)+4
which is equal to 14, not 36 which might have been expected.
Why is variable "i" incremented twice? i.e to 5 from 3 after j=prod(i++)
Because prod() is a macro, not a function, so
k=prod(++i);
become
k=(++i * ++i);
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,
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
I have simple logging class as below.
#include <iostream>
#include <string>
using namespace std;
class log
{
public:
log(){};
~log(){};
log & operator << ( int x ){ cout << x; return * this;}
log & operator << ( string x ){ cout << x; return * this;}
log & operator << ( log & (log::*pf)() ){ (this->*pf)(); return * this;}
log & end( ) { cout << "\r\n"; return * this;}
};
log l;
#define end &log::end;
#define error( z ) l << "ERROR " z << end;
#define warn( z ) l << "WARN " z << end;
int main()
{
int y = 20;
error ( << y );
}
Is there any way that I can write my code in main like this?
error << y;
Basic idea here, is to avoid user to use macro end
i.e. I do not want user to code like below
error << y << end;
Look like you are reinventing the square wheel to me ! Indeed, there are a lot of logger library out there (boost.log is a good one). Another solution is to have the user write the standard syntax including the call to std::endl:
error << x << std::endl;
warn << y << std::endl;
You can do that by passing a string "warn" or "error" to the construtor of class log.
You have to intercept the std::endl parameter as described in Overload handling of std::endl?.
What about:
#define LOG(Msg) do { l << Msg << ::std::endl; } while(0)
Log("Hello" << "World");
Note: I use a macro like this in debug builds and make it ((void)0) in release builds.
For common logging you should not use a macro and may consider stream manipulators.
One option would be to remove your global variable and use your destructor to write the newline by having the macros create a scope so the object is destroyed:
#define error( z ) {log l; l << "ERROR " z; }
#define warn( z ) {log l; l << "WARN " z; }
That would yield code close to what it appears you want without your end macro:
int y = 20, z = 40;
error ( << y << " " << z);
If you like that approach you might want to look into improving the macro so log levels are enforced in the macro itself so objects are not created with every log message that have nothing to do, if performance at that level matters to you.
Don't see a plug for POCO logging anywhere in here, that's what I use. Not saying that would work for you, it's just what I like for my particular needs.
You may create class:
class PrefixLog
{
public:
explicit PrefixLog(const char* prefix) : prefix(prefix) {}
template <typename T>
log& operator << (const T& t) const { return l << prefix << t << &log::end; }
private:
const char* prefix;
};
PrefixLog error("ERROR ");
PrefixLog warning("WARN ");
And then
warning << y;
error << y;
I'm basically looking for a way to automate typing stuff like the following:
cout << "a[" << x << "][" << y << "] =\t" << a[x][y] << endl;
Something like:
PRINTDBG(a[x][y]);
Ideally this would also work for
PRINTDBG(func(arg1, arg2));
and even
PRINTDBG(if(condition) func(foo););
(which would print e.g. "if(false) func(5)").
Nonportable hacks welcome too :)
(no, using a debugger isn't the same, it's much less flexible and I find it confusing)
This is, in the way you want it, not possible. If you have if(condition) func(foo); given to a macro, it can stringize that stuff, and it will print if(condition) func(foo);, but not with the actual values of the variables substituted. Remember the preprocessor doesn't know about the structure about that code.
For debugging, i would use some type-safe printf variant like boost.format or some home brew printf with boost.fusion, which make the job of printing stuff like that much more easy:
dprintf("a[%][%] = %", (x, y, a[x][y]));
This is an area where the printf style output can be more concise:
cout << "a[" << x << "][" << y << "] =\t" << a[x][y] << endl;
printf("a[%d][%d] =\t%d\n", x, y, a[x][y]);
Of course, this has the limitation of only working for types that printf understands, and it still doesn't address your question.
I get the feeling that there might be something of value in the expression decomposition techniques in Boost, but I am not enough of a template ninja to identify what.
Update: The following almost addresses your question:
#define PRINTDBG(x) cout << #x << " =\t" << x << endl;
However, when used as PRINTDBG(a[x][y]) it literally prints:
a[x][y] = 5
which doesn't give the actual values of x and y.
I typically use a simple, but customizable logger function instead of macros
Log(const char *format, ...)
{
char buffer[MAX_BUFFER_SIZE];
va_list args;
//get arguements into a list
va_start(args, format);
//printf formated arguement into a string
vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
printf("%s", buffer);
}
so now you can do
Log("a[%d][%d] =\t%d\n", x, y, a[x][y])
Log("if(%s) func(%d) ;", (condition) ? "true" : "False", func(foo))
add in some loggingtype (i.e. LOG_SCREEN, LOG_FILE) to the function Log() and now you can control where is gets logged to
add in some logginglevel (i.e. WARN, CRIT) to control how it gets displayed, color etc.
Of course there are many, many library's out there that do all this type of stuff already
hope this helps
In a slight expansion in a different direction to Greg's posting, I've seen some nice C programs that look something like this
#DEFINE DEBUG_MODE 1
//...
if( DEBUG_MODE)
printf("methodX() says: y=%i, var1=%i", y, var1);
However you still have a ton of printf's in your program, but at least you can turn them all on and off when you want to.
you can define operator« for custom classes so you only have to define formatting once:
struct point3 {
int x,y,z;
point3(int a, int b, int c){x=a;y=b;z=c;}
};
std::ostream& operator << (std::ostream& os, const point3& f) {
return os << "(" << f.x << "," << f.y << "," << f.z << ")";
}
point3 p(1,2,3);
std::cout << p; // prints "(1,2,3)"
this pairs well with redirecting cout or clog to a file (don't recall how std::clog works)
#include <iostream>
#include <fstream>
int main() {
std::ofstream file("log.txt");
std::streambuf *filebuf = file.rdbuf();
std::cout.rdbuf(filebuf);
std::cout << "This is written to the file";
filestr.close();
return 0;
}