Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Preprocessor trick?

Reply
Thread Tools

Preprocessor trick?

 
 
SerGioGio
Guest
Posts: n/a
 
      01-22-2005
Hello,

Is there a way to #define a (set of) macro that will turn:
FUNC(a)(b)(c)
into:
func(a, b, c)
regardless of the number of parameters?

i.e:
FUNC(a)(b)(c) ---> func(a, b, c)
FUNC(a)(b) ---> func(a, b)
FUNC(a) ---> func(a)

Despite my efforts I can't find one so I am wondering whether there actually
is.

Thanks in advance!

SerGioGio


 
Reply With Quote
 
 
 
 
puzzlecracker
Guest
Posts: n/a
 
      01-22-2005

SerGioGio wrote:
> Hello,
>
> Is there a way to #define a (set of) macro that will turn:
> FUNC(a)(b)(c)
> into:
> func(a, b, c)
> regardless of the number of parameters?
>
> i.e:
> FUNC(a)(b)(c) ---> func(a, b, c)
> FUNC(a)(b) ---> func(a, b)
> FUNC(a) ---> func(a)
>
> Despite my efforts I can't find one so I am wondering whether there

actually
> is.
>
> Thanks in advance!
>
> SerGioGio


NO!

 
Reply With Quote
 
 
 
 
Mike Wahler
Guest
Posts: n/a
 
      01-22-2005
"SerGioGio" <(E-Mail Removed)> wrote in message
news:41f1a9fa$(E-Mail Removed)...
> Hello,
>
> Is there a way to #define a (set of) macro that will turn:
> FUNC(a)(b)(c)
> into:
> func(a, b, c)
> regardless of the number of parameters?
>
> i.e:
> FUNC(a)(b)(c) ---> func(a, b, c)
> FUNC(a)(b) ---> func(a, b)
> FUNC(a) ---> func(a)
>
> Despite my efforts I can't find one so I am wondering whether there

actually
> is.


I'm not sure, but I've seen some rather clever tricks done
with macros. BUT: I wouldn't even try, because:
Why do you want to do this? Macros don't allow for the level of
type saftey and error checking that functions do (all they are
is a text-substitution mechanism). Their necessity is much less
in C++ than in C. Especially in the context you ask about,
because C++ has function overloading and default parameters.


Overloaded functions:

/* A */ void func(int a){}
/* B */ void func(int a, int b){}
/* C */ void func(int a, int b, int c){}

int main()
{
func(1); /* calls version A */
func(1, 2); /* calls version B */
func(1, 2, 3); /* calls version C */
return 0;
}

Default paramters:

void func(int a = 0, int b = 0, int c = 0){}

int main()
{
func(); /* same as func(0, 0, 0); */
func(1); /* same as func(1, 0, 0); */
func(1, 2); /* same as func(1, 2, 0); */
func(1, 2, 3);
return 0;
}

(The defaults can be any values you want, and the
function need not refer to any parameters not
applicable to a particular call).

-Mike


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      01-22-2005
"SerGioGio" <(E-Mail Removed)> wrote...
> Hello,
>
> Is there a way to #define a (set of) macro that will turn:
> FUNC(a)(b)(c)
> into:
> func(a, b, c)
> regardless of the number of parameters?
>
> i.e:
> FUNC(a)(b)(c) ---> func(a, b, c)
> FUNC(a)(b) ---> func(a, b)
> FUNC(a) ---> func(a)
>
> Despite my efforts I can't find one so I am wondering whether there
> actually
> is.


Well, it's relatively simple to prove that there can be no such macro.
If you write

FUNC(a)(b)

why should the preprocessor continue looking ahead for (b), when it can
stop right there and simply substitute FUNC(a) with func(a)? So, the
preprocessor cannot decide, I guess.

You can simulate this with C++, though. By overloading operator() and
defining what value it returns, you probably could make it so if you
write

func1(a)(b)(c)

it actually eventually calls some func(a,b,c)... I'll leave it for you
to try.

V


 
Reply With Quote
 
Jonathan Turkanis
Guest
Posts: n/a
 
      01-22-2005

"SerGioGio" <(E-Mail Removed)> wrote in message
news:41f1a9fa$(E-Mail Removed)...
> Hello,
>
> Is there a way to #define a (set of) macro that will turn:
> FUNC(a)(b)(c)
> into:
> func(a, b, c)
> regardless of the number of parameters?
>
> i.e:
> FUNC(a)(b)(c) ---> func(a, b, c)
> FUNC(a)(b) ---> func(a, b)
> FUNC(a) ---> func(a)


Victor's argument that it can't be done sounds right, but my intuitions about
the preprocessor are often wrong.

It can *almost* be done, though, using the Boost Preprocessor Metaprogramming
library:

Program:

#include <boost/preprocessor/seq/enum.hpp>

#define FUNC(seq) func(BOOST_PP_SEQ_ENUM(seq))

FUNC((a))
FUNC((a)(b))
FUNC((a)(b)(c))

Preprocessed output:

func(a)
func(a, b)
func(a, b, c)

> SerGioGio


Jonathan


 
Reply With Quote
 
Alan Krueger
Guest
Posts: n/a
 
      01-22-2005
SerGioGio wrote:
> Is there a way to #define a (set of) macro that will turn:
> FUNC(a)(b)(c)
> into:
> func(a, b, c)
> regardless of the number of parameters?


The specific example with three parameters might be constructed like this:

#define A(x) x)
#define B(x) x,A
#define SUM(x) sum(x,B

int sum( int a, int b, int c )
{
return a + b + c;
}

int a = 2;
int b = 3;
int c = 5;
int s = SUM(a)(b)(c);

Not sure if iterative replacement is standard, or just supported by the
compiler I'm using, but this last line gets transformed to

int s = sum(a,b,c);

Doing this for *any* number of parameters with a single set of macros is
unlikely, because you'd have to use a recursive macro, which cannot be
propertly terminated.
 
Reply With Quote
 
SerGioGio
Guest
Posts: n/a
 
      01-22-2005
>
> I'm not sure, but I've seen some rather clever tricks done
> with macros. BUT: I wouldn't even try, because:
> Why do you want to do this? Macros don't allow for the level of
> type saftey and error checking that functions do (all they are
> is a text-substitution mechanism). Their necessity is much less
> in C++ than in C. Especially in the context you ask about,
> because C++ has function overloading and default parameters.
>


Actually I would like to get the text of the arguments, not only their
values...
so I can only use a macros and #x command.
This could be achieved using a FUNC(a, b, c) macro but the FUNC(a)(b)(c)
form suits more to the purpose.

SerGioGio


 
Reply With Quote
 
SerGioGio
Guest
Posts: n/a
 
      01-22-2005
> Not sure if iterative replacement is standard, or just supported by the
> compiler I'm using, but this last line gets transformed to
>
> int s = sum(a,b,c);
>
> Doing this for *any* number of parameters with a single set of macros is
> unlikely, because you'd have to use a recursive macro, which cannot be
> propertly terminated.


Yes, it really looks like doing it for any number of parameters is
impossible.
I tried the following:

#define FUNC2(x) func(dummy FUNC2_END_A(x)
#define FUNC2_END_A(x) ,x FUNC2_END_B
#define FUNC2_END_B(x) ,x FUNC2_END_A

which does:

FUNC2(a)(b)(c) --> func(dummy ,a ,b ,c FUNC2_END_B
FUNC2(a)(b) --> func(dummy ,a ,b FUNC2_END_A
FUNC2(a) --> func(dummy ,a FUNC2_END_B

unfortunately there is no way to transform subsequentely... FUNC2_END_A and
FUNC2_END_B into )

The solution I am now considering is doing:

enum FUNC6_END { FUNC6_END_A, FUNC6_END_B };
#define FUNC6(x) func* FUNC6_END_A(x)
#define FUNC6_END_A(x) (x)*(#x)*FUNC6_END_B
#define FUNC6_END_B(x) (x)*(#x)*FUNC6_END_A

which does:

FUNC6(a)(b)(c) --> func*(a)*(#a)*(b)*(#b)*(c)*(#c)*FUNC6_END_A
FUNC6(a)(b) --> func*(a)*(#a)*(b)*(#b)*FUNC6_END_B
FUNC6(a) --> func*(a)*(#a)*FUNC6_END_A

As you can see, my aim is to get the text and values of all the "arguments"
of the macro FUNC6, and that is why I can't just use overload operator().

This solution requires slightly more complicated code, possibly slighlty
slower, and there may be a problem with the precedence of operators. But it
looks its the closest solution.

SerGioGio


 
Reply With Quote
 
=?ISO-8859-1?Q?Tobias_G=FCntner?=
Guest
Posts: n/a
 
      01-22-2005
SerGioGio wrote:
> #define FUNC2(x) func(dummy FUNC2_END_A(x)
> #define FUNC2_END_A(x) ,x FUNC2_END_B
> #define FUNC2_END_B(x) ,x FUNC2_END_A


enum FUNC_END { FUNC2_END_A, FUNC2_END_B }
#define FUNC2(x) func(FUNC2_END_A(x)
#define FUNC2_END_A(x) x, FUNC2_END_B
#define FUNC2_END_B(x) x, FUNC2_END_A

> FUNC2(a)(b)(c) --> func(dummy ,a ,b ,c FUNC2_END_B
> FUNC2(a)(b) --> func(dummy ,a ,b FUNC2_END_A
> FUNC2(a) --> func(dummy ,a FUNC2_END_B


FUNC2(a)(b)(c)) --> func(a, b, c, FUNC2_END_B)
FUNC2(a)(b)) --> func(a, b, FUNC2_END_A)
FUNC2(a)) --> func(a, FUNC2_END_B)

If you
#define FUNC3(x) FUNC2 x )
it should be possible to write FUNC3((a)(b)(c)), which looks
much nicer

A different approach:

extern class func_t
{
public:
func_t() :
FUNC_END_A(*this), FUNC_END_B(*this) {}

template<class T>
func_t& operator()(const ::std:air<T, const char*>& param)
{
std::cout << param.second << ": " <<
param.first << "\n";
return *this;
}

func_t& FUNC_END_A;
func_t& FUNC_END_B;

} func;

#define FUNC func.FUNC_END_A
#define FUNC_END_A(x) FUNC_END_A(::std::make_pair(x, #x)).FUNC_END_B
#define FUNC_END_B(x) FUNC_END_B(::std::make_pair(x, #x)).FUNC_END_A

// in some cpp file
func_t func;

int main()
{
int a = 0, b = 1, c = 2;
FUNC(a)(b)(c);
FUNC(a)(b);
FUNC(a);
}

--
Regards,
Tobias
 
Reply With Quote
 
Thomas Matthews
Guest
Posts: n/a
 
      01-22-2005
SerGioGio wrote:
> Hello,
>
> Is there a way to #define a (set of) macro that will turn:
> FUNC(a)(b)(c)
> into:
> func(a, b, c)
> regardless of the number of parameters?
>
> i.e:
> FUNC(a)(b)(c) ---> func(a, b, c)
> FUNC(a)(b) ---> func(a, b)
> FUNC(a) ---> func(a)
>
> Despite my efforts I can't find one so I am wondering whether there actually
> is.
>
> Thanks in advance!
>
> SerGioGio
>
>


I believe a better design would be to pass a structure
to the function that contains information about the
parameters, such as quantity, locations and type.

enum Parameter_Type
{
PT_CHAR, PT_UCHAR, PT_INT, PT_UINT,
PT_DOUBLE, PT_FLOAT, PT_LONG
};

struct Param_Attributes
{
enum Parameter_Type type;
void * pointer_to_data;
}

void Process_Parameters(struct Param_Attributes * array,
size_t quantity)
{
/* ... */
}

The idea here is that one function is used for multiple
data types versus one function for each quantity and
variation of types.

Just a thought...

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Compiler error occurred when try to use a flexible template expression in preprocessor definesCompiler error occurred when try to use a flexible template expression in preprocessor defines snnn C++ 6 03-14-2005 04:09 PM
C# Preprocessor =?Utf-8?B?SSBhbSBTYW0=?= ASP .Net 2 03-13-2005 02:47 PM
preprocessor, token concatenation, no valid preprocessor token Cronus C++ 1 07-14-2004 11:10 PM
VHDL Preprocessor The Weiss Family VHDL 2 07-14-2004 05:51 AM
Preprocessor conditional compilation variable not being saved Chris P ASP .Net 0 10-28-2003 08:48 PM



Advertisments