Conditional Define

B

BQ

Dik T. Winter said:
And indeed that will be done. But this is a bit different. With FUNC as
you see it, FUNC(56) could be expanded by the preprocessor, but FUNC(x)
not when x is a variable. On the other hand, a good optimising compiler
will expand FUNC(56) also with the conditional expression to a single
constant. gcc will do it.

Yes, I agree with you - but I've to rely on the compiler, and in particular it's not my
case...
Regards,
BQ
 
J

Jarno A Wuolijoki

I had the same idea originally, but then I thought that doesn't answer
the OP's question. Your preprocessing code will first evaluate a
variable X, and then either expand every "result_of_funct" macro to 56,
or expand every "result_of_funct" macro to 20. What the OP wants is to
evaluate the parameter of result_of_funct macro *SEPARATELY* and expand
the macro to either 56 or 20 depending on its value. For example the
code:

result_of_funct(36); result_of_funct(34);

should get expanded to:

56; 20;

Neither my original code or your code is able to do this.

Depends on how you use it.

funct.h:

#if X > 35
56
#else
20
#endif
#undef X

Now instead of using funct() you define X and include funct.h.

I have written a code unroller with an interface like this, but
I've yet to find any realistic use for it:)
 
B

BQ

Case said:
Again, what does ISNEAR() look
like? I suppose trying another is not an option.

Kees

Sorry for the late. I need more time because I assumed that my ISNEAR worked...
 
C

Case

BQ said:
"BQ" <[email protected]> ha scritto nel messaggio





Sorry, as you already have understood, I meant

c=FUNCT(A);
d=FUNCT(B);

If A and B can only be one of a small set of values then
you could define your FUNC multiple times (once for each
possible A/B value) and use the ## preprocessor directive
to select the right FUNCT()

#define FUNCT10() ...........
#define FUNCT20() ......
#define FUNCT56() .........
#define FUNCT.....

#define FUNCT(x, y) FUNCT ## x (y)

Kees
 
D

Dan Pop

Joona I Palaste said:
Martin Buchleitner said:
[CUT]

I had the same idea originally, but then I thought that doesn't answer
the OP's question. Your preprocessing code will first evaluate a
variable X, and then either expand every "result_of_funct" macro to 56,
or expand every "result_of_funct" macro to 20. What the OP wants is to
evaluate the parameter of result_of_funct macro *SEPARATELY* and expand
the macro to either 56 or 20 depending on its value. For example the
code:

result_of_funct(36); result_of_funct(34);

should get expanded to:

56; 20;

Thank you Joona, this is *exactly* what I meant (and what I need in my code).
I'm concerned about that fact that this can be determined at compile time, so I suppose
that there must be a way to do what I need.

Maybe that

#define FUNCT(x) #if (x>35) 56 #else 20 #endif

has problems because it needs two passes of the preprocessor (one in which it substitutes
each instance of 'FUNCT', one in which the preprocessor solves the #if clause).

It has problems because macros can't expand to other preprocessor
directives. The solution to your problem exists, but it's not
particularly elegant:

#define THRESH 35
#define VAL1 56
#define VAL2 20

....
#undef FUNCT
#if 100 > THRESH
#define FUNCT VAL1
#else
#define FUNCT VAL2
#endif

Note that the second block of directives must appear *every* time you need
to convert a value, 100 in my example, according to your algorithm, at
compile time. After that, you can simply use FUNCT. As I said, it *is*
ugly, but it solves the following problems:

1. Everything is computed by the preprocessor

2. If one of the constants of the conversion algorithm (THRESH, VAL1,
VAL2) changes, the change is made in only one place.

The other solution relies on the compiler's ability to evaluate constant
expressions at compile time:

#define FUNCT(x) (x > 35 ? 56 : 20)

If x is a constant (as it is supposed to be), FUNCT(x) evaluates to
a constant expression that any decent compiler should exaluate at
compile time. You have to test the code generated by your compiler
to see whether it indeed replaces this expression by 56 or 20.

Dan
 
K

Keith Thompson

BQ said:
Hello

Is there a way to declare 'FUNCT' via a define so that if its
parameter x, a constant, is greater than 35, it returns 56, if not,
20. I would like that at compile time, not at run time.

After reading your other articles in this thread, I think you're
dealing with a compiler that won't evaluate conditional expressions at
compilation time. If it's smart enough to evaluate arithmetic
expressions, including relational operators, at compilation time
(e.g., replacing 2+2 with 4 and 2<3 with 1), the following might suit
your purposes:

#define FUNCT(x) (56 * ((x)>35) + 20 * ((x)<=35))

Here's a complete program that demonstrates it:

#include <stdio.h>

#define FUNCT(x) (56 * ((x)>35) + 20 * ((x)<=35))

int main(void)
{
printf("FUNCT(34) = %d\n", FUNCT(34));
printf("FUNCT(35) = %d\n", FUNCT(35));
printf("FUNCT(36) = %d\n", FUNCT(36));
return 0;
}

With the compiler I just tried, it produces the following output:

FUNCT(34) = 20
FUNCT(35) = 20
FUNCT(36) = 56

An assembly listing shows no references to the values 34, 35, or 36,
just literal values 20, 20, and 56.
 
P

Paul Mensonides

Case said:
If A and B can only be one of a small set of values then
you could define your FUNC multiple times (once for each
possible A/B value) and use the ## preprocessor directive
to select the right FUNCT()

#define FUNCT10() ...........
#define FUNCT20() ......
#define FUNCT56() .........
#define FUNCT.....

#define FUNCT(x, y) FUNCT ## x (y)

Boost.Preprocessor can perform this operation in several ways. Here's one:

#include <boost/preprocessor/comparison/greater.hpp>
#include <boost/preprocessor/control/iif.hpp>

#define FUNCT(x) \
BOOST_PP_IIF(BOOST_PP_GREATER(x, 35), 56, 20) \
/**/

This will work provided x is between 0 and 256.

Regards,
Paul Mensonides
 
P

Peter Nilsson

Case said:
If A and B can only be one of a small set of values then
you could define your FUNC multiple times (once for each
possible A/B value) and use the ## preprocessor directive
to select the right FUNCT()

#define FUNCT10() ...........
#define FUNCT20() ......
#define FUNCT56() .........
#define FUNCT.....

#define FUNCT(x, y) FUNCT ## x (y)

ITYM:

#define FUNCT10 20
#define FUNCT20 20
#define FUNCT34 20
#define FUNCT36 56

#define CAT(x,y) x ## y
#define FUNCT(x) CAT(FUNCT,x)

FUNCT(10)
FUNCT(20)
FUNCT(34)
FUNCT(36)

#define A 36
FUNCT(A)
 
J

Jack Klein

Boost.Preprocessor can perform this operation in several ways. Here's one:

#include <boost/preprocessor/comparison/greater.hpp>
#include <boost/preprocessor/control/iif.hpp>

[snip]

And exactly what is that supposed to mean in comp.lang.c?
 
P

Paul Mensonides

Jack said:
Boost.Preprocessor can perform this operation in several ways.
Here's one:

#include <boost/preprocessor/comparison/greater.hpp>
#include <boost/preprocessor/control/iif.hpp>

[snip]

And exactly what is that supposed to mean in comp.lang.c?

Unlike the rest of Boost, Boost.Preprocessor is both a C and C++ library.

Regards,
Paul Mensonides
 
R

Richard Bos

Paul Mensonides said:
Jack Klein wrote:

[ No, he didn't. Do not over-snip attributions. ]
Unlike the rest of Boost, Boost.Preprocessor is both a C and C++ library.

And is this Boost Preprocessor written in, and _completely_ compatible
with, ISO C? And is the source code readily available so we can check
this?

Richard
 
C

Case

Peter said:
ITYM:

#define FUNCT10 20
#define FUNCT20 20
#define FUNCT34 20
#define FUNCT36 56

#define CAT(x,y) x ## y
#define FUNCT(x) CAT(FUNCT,x)

FUNCT(10)
FUNCT(20)
FUNCT(34)
FUNCT(36)

#define A 36
FUNCT(A)
Yep, that's more like it. Thanks for the addition, I was a
bit in a hurry yesterday.

Kees
 
B

BQ

BQ said:
Hello
Is there a way to declare 'FUNCT' via a define so that if its parameter x, a constant, is
greater than 35, it returns 56, if not, 20.
I would like that at compile time, not at run time.
So:
#define FUNCT(x) x>35?56:20
is not the answer to my question.
Could be something like
#define FUNCT(x) #if (x>35) 56 #else 20 #endif
Since the 'x' is a constant, this can be done by the preprocessor, so I suppose there's a
way to do it.
Maybe it's a stupid question but is there a solution to this issue?
Thank you in advance,
Marco Lazzaroni

Thank you all for your useful replies that helped me in better understanding the
preprocessor.
After re-examining the problem many times I found out that it can be reduced to the need
of writing:

#define FUNCT(x) #if TEST(x) Y1(x) #else Y2(x) #endif

But as clearly stated in the FAQ, 10.14, the preprocessor can't be called on itself.

I have to use FUNCT(x) with about hundreds of different costant values for x. This
prevents the use of the interesting ## directive for reasons of readability and
re-usability of the code.
Obviously there are many ways to achieve what I need with smarter coding, without need of
macros. But my major issue is about code space and I can't choose this solution. So, since
I can't even rely on the compiler's efficiency - as considered in some of the posts - I
will write a small pre-preprocessor.

Thank you all again! :)

Regards,
Marco Lazzaroni
 
Z

ZAPPLE

BQ said:
Thank you all for your useful replies that helped me in better understanding the
preprocessor.
After re-examining the problem many times I found out that it can be reduced to the need
of writing:

#define FUNCT(x) #if TEST(x) Y1(x) #else Y2(x) #endif

But as clearly stated in the FAQ, 10.14, the preprocessor can't be called on itself.

I have to use FUNCT(x) with about hundreds of different costant values for x. This
prevents the use of the interesting ## directive for reasons of readability and
re-usability of the code.
Obviously there are many ways to achieve what I need with smarter coding, without need of
macros. But my major issue is about code space and I can't choose this solution. So, since
I can't even rely on the compiler's efficiency - as considered in some of the posts - I
will write a small pre-preprocessor.

Thank you all again! :)

Regards,
Marco Lazzaroni

Hi Guys,
I think the previous one is a very good example and explanation for your question
ZAPPLE
 

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

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,817
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top