Answer to Francesco S. Carta

P

PowerStudent

Purpose of my Macros in short:

o PFUNC(R,N,P) typedef R (*N)(P)
I use this macro to define myself different function pointer types.
These functions look like this:
RETURN_TYPE NAME(PARAMETER_TYPE param);

RETURN_TYPE, PARAMETER_TYPE can be: void, int, char, float

For exemple:
// assume there is a function int blabla();
PFUNC(int, piFunkv,void);
piFunkv myPointer = blabla;

o FUNC(R,N,P)
This macro declares my functions I want my pointers to point to.

The resulting functions look like this:
(*) R N(T in);

only exception of the rule:
FUNC(R, N, void); produces the following function:
R N();
o NEW_VAR(R, N, V)
This macro declares new variables, if R is unequal to void.
Otherwise the preprocessor just leaves white space.
o PRINT(R, N, V)
This macro prints the return type, the name and (if there is a
parameter) the parameter type and name of the function it's standing
in.
Where possible, it also prints out the returned value and the
parameter value.
o RETURN(R, N)
This macro is either replaced by return; - RETURN(void, N); - or by
return N; - RETURN(R, N);.
o CREATE(R, N)
This macro defines function pointer types und defines & declares
functions and corresponding pointers

exemple:
CREATE(void, vFunc);
//=>
typedef void (*pvFuncv)(void);
typedef void (*pvFuncc)(char);
typedef void (*pvFunci)(int);
typedef void (*pvFuncf)(float);
void vFuncv(void){
//...
}
void vFuncc(char){
//...
}
void vFunci(int){
//...
}
void vFuncf(float){
//...
}
const pvFuncv pvFuncvVar = vFuncv;
const pvFuncc pvFunccVar = vFuncc;
const pvFunci pvFunciVar = vFunci;
const pvFuncf pvFuncfVar = vFuncf;

o CALL(P, V)
Calls every function defined in funcs.h which parameter is of type P
with the given value V.

The cause why I have so many FUNC_*, NEW_VAR_*, *_PRINT_*, RETURN_*
macros defined is that some parameters of FUNC would have created
functions that aren't allowed in C++:
// If FUNK would create all functions like defined above (*), then the
following call
FUNC(void, notWorking, void);

// would have the following result:

// multiple errors: there can't be a variable of type void
void notWorking(void in){
void result = static_cast<void>(in);
printf("The function void %s(void in) was called and returned %?.
Value of in: %?", notWorking, result, in);
return result;
}

First I tried to use MACROS inside MACROS, like
#define IS_VOID(T) IS_VOID_##T
#define IS_VOID_true true
#define IS_VOID_false false
#define RETURN(R, N) #if ( IS_VOID(R) ) \ return; \ #else \ return N

But this doesn't work.

P.S. @Francesco S. Carta : I actually tried cout first, but then my
source code became very untidy and I couldn't get it to work properly,
so I switched to printf which was easier to use.
 
F

Francesco S. Carta

Purpose of my Macros in short:

In short? What if I asked for a detailed dissertation ;-)

Just joking, I do actually appreciate your effort and I hope you will
appreciate mine, in this post.

Besides, it would have been better posting this as a follow-up to the
thread where it belongs, just for continuity of discussion (also for
future readers... I think I'll add a post there to rejoin these two).

Let's not speak about the subject line you've chosen, which is... well,
never mind ;-)

<snip macros explanation>

This is the sentence of mine that led you to post those explanations:
"I'll try to understand what exactly your macros do, although a small
briefing from you would make things easier for me."

What I meant to ask was what code you were going to create, not the way
you was going to create it. As it turned out, you wanted a series of
automatically created functions taking parameters of different types and
returning different types too (let's put aside the pointers to those
functions, for the moment).

Coding all of those functions by hand wasn't wise, and obviously you
recurred to a tool that you knew, the preprocessor, which is fine in C,
but in C++ such kind of things is done with templates - although in this
very case the preprocessor can still come quite useful - for example:

//-------
#include <iostream> // cout, endl
#include <typeinfo> // typeid

using namespace std;

template <typename T>
const char* Keyword(T) {
#define MATCH_KEY(K) \
if(typeid(T) == typeid(K)) \
return #K ; \
if(typeid(T) == typeid(const K)) \
return "const " #K ; \
if(typeid(T) == typeid(K *)) \
return #K " *" ; \
if(typeid(T) == typeid(const K *)) \
return "const " #K " *" ; \
if(typeid(T) == typeid(K * const)) \
return #K " * const" ; \
if(typeid(T) == typeid(const K * const)) \
return "const " #K " * const"
MATCH_KEY(char);
MATCH_KEY(short);
MATCH_KEY(int);
MATCH_KEY(long);
MATCH_KEY(long long);
MATCH_KEY(signed char);
MATCH_KEY(unsigned char);
MATCH_KEY(unsigned short);
MATCH_KEY(unsigned int);
MATCH_KEY(unsigned long);
MATCH_KEY(unsigned long long);
MATCH_KEY(float);
MATCH_KEY(double);
MATCH_KEY(long double);
#undef MATCH_KEY
return typeid(T).name();
}

template <typename Type>
void NoReturn(Type param) {
cout << "NoReturn(" << Keyword(param) << ")";
cout << " == " << param << endl;
}

template <typename Type>
Type PassMe(Type param) {
cout << "PassMe(" << Keyword(param) << ")";
cout << " == " << param << endl;
return param;
}

template <typename ReturnType, typename ParamType>
ReturnType GimmeA(ParamType param) {
ReturnType result = ReturnType(param);
cout << "GimmeA<" << Keyword(result) << ">";
cout << "(" << Keyword(param);
cout << " = " << param << ")";
cout << " == " << result << endl;
return result;
}

int main() {
#define EXECOUT(E) cout << "\n " << #E << "\n# " ; E
EXECOUT( NoReturn(78U); );
EXECOUT( unsigned char uch = PassMe(0x2AUL); );
EXECOUT( const int id = GimmeA<short>(1.23F); );
EXECOUT( size_t say = GimmeA<size_t>(&id); );
EXECOUT( return 0*uch*id*say; );
}
//-------

Now, I know that the above can look cryptic to someone who isn't
accustomed to deal with templates, but since you have been able to build
that big macro castle, the above shouldn't really intimidate you:
templates are something like macros on steroids under this aspect, and
you should be able to understand the program above in very little time.

All questions are welcome, but please stay in the same thread unless you
really need to create a new one ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,815
Latest member
treekmostly22

Latest Threads

Top