Conditional Define

B

BQ

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
 
J

Joona I Palaste

BQ said:
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.

#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,

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

Barring some preprocessor syntax errors, you're now in for a "why
didn't I think of that?" slap on the forehead.
 
A

Allan Bruce

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

this is wrong. #XXX are pre-processor defines so do not know anything about
the values that variables take during execution.
Since the 'x' is a constant, this can be done by the preprocessor, so I suppose there's a
way to do it.

No, unless you use a #define for the 'const' you mean.
Maybe it's a stupid question but is there a solution to this issue?
Thank you in advance,

Marco Lazzaroni

Its not s stupid question, but my immediate response is, why? why doesnt
x>35?56:20 suffice?
Allan
 
J

Joona I Palaste

BQ said:
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.

#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,

Forget my earlier reply (now cancelled). It used a global variable "x"
as the parameter in the #if, not the parameter x in the macro itself.
I don't think what you really want to do is possible at all. Keep in
mind that the actual value of the argument for your macro isn't known
until run-time, so #defining it to either 56 or 20 at compile time
would require clairvoyance.
 
M

Martin Buchleitner

* "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.


#if X > 35
#define result_of_funct 56
#else
#defince result_of_fucnt 20
#endif

What about that?



mabu
 
N

Nick Landsberg

Joona said:
Forget my earlier reply (now cancelled). It used a global variable "x"
as the parameter in the #if, not the parameter x in the macro itself.
I don't think what you really want to do is possible at all. Keep in
mind that the actual value of the argument for your macro isn't known
until run-time, so #defining it to either 56 or 20 at compile time
would require clairvoyance.

gcc -DX=52 foo.c

would set the value of X at compile time
and your original macro's should evaluate properly.
No? Or is that cheating?
 
B

BQ

Allan Bruce said:
[CUT]
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

this is wrong. #XXX are pre-processor defines so do not know anything about
the values that variables take during execution.
[CUT]

Its not s stupid question, but my immediate response is, why? why doesnt
x>35?56:20 suffice?
Allan

Hehe I supposed that I would be generating this kind of questions :)
Sorry but I didn't explain clearly enough.
I'm working on a small microprocessor (and when I say small I mean 32k of ROM and 1536 of
RAM) so I'm really focused on ROM occupation issues.

I want to point out anyway that I'd always use FUNCT with a constant defined by a #define.

x>35?56:20 would generate an 'if' statement that generates relatively a lot of code.
I suppose that a good compiler substitutes

if (3>2) 5;

with

5

But it's not my case....

Marco
 
A

Allan Bruce

BQ said:
Allan Bruce said:
[CUT]
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

this is wrong. #XXX are pre-processor defines so do not know anything about
the values that variables take during execution.
[CUT]

Its not s stupid question, but my immediate response is, why? why doesnt
x>35?56:20 suffice?
Allan

Hehe I supposed that I would be generating this kind of questions :)
Sorry but I didn't explain clearly enough.
I'm working on a small microprocessor (and when I say small I mean 32k of ROM and 1536 of
RAM) so I'm really focused on ROM occupation issues.

I want to point out anyway that I'd always use FUNCT with a constant defined by a #define.

If you are working on that amount of memory, then perhaps ASM is the way to
go.
an if statement shouldnt produce lots of code. In a pseudo-asm code.

CMP x,value ;// compare x with value
JMPZN;// skip if the status flag of last was negative
GOTO xxx;// x is greater than value, so goto the given line of execution

so thats only 3 lines of assembly, which is probably about 6bytes +
sizeof(int)

Allan
 
J

Joona I Palaste

#if X > 35
#define result_of_funct 56
#else
#defince result_of_fucnt 20
#endif
What about that?

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.
 
B

BQ

Allan Bruce said:
BQ said:
"Allan Bruce" <[email protected]> ha scritto nel messaggio
news:[email protected]...
[CUT}]

CMP x,value ;// compare x with value
JMPZN;// skip if the status flag of last was negative
GOTO xxx;// x is greater than value, so goto the given line of execution

so thats only 3 lines of assembly, which is probably about 6bytes +
sizeof(int)

Allan

Allan,
the real define I need is used about 500 times in the code, so this would be a large
waste of space (and cpu time).

In particular, that define is a bit access that is different depending on the location of
the byte (near, far) containing the bit I need to test/bit/set.
At compile time, I know if that particular byte is in near or in far memory.

Having defined

typedef struct {
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
} BOOL;

and

#define BIT(byte,bit) (*((BOOL*)&byte)).bit

Where bit can be b0,b1,b2...b7.

And so I can access a bit in the memory.
Compiling it, I get 2 ASM instructions.
Anyway if I use this definition, valid only for near memory:

#define BIT(byte,bit) (*((near BOOL*)&byte)).bit

....I would get 1 single ASM instruction.


So, provided that I have a way to determine AT COMPILE TIME if I am able to use this
second define (and I can) (let call this macro ISNEAR(byte)),
I would like to write something like this:

#define BIT(byte,bit) #if ISNEAR(byte) ( (*((near BOOL*)&byte)).bit ) #else (
(*((BOOL*)&byte)).bit ) #endif

Regards,

Marco
 
B

BQ

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).

Regards,

Marco Lazzaroni
 
J

Joona I Palaste

BQ said:
Joona I Palaste said:
Martin Buchleitner said:
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.

Suppose your code has something like:
int x;
scanf("%d", &x);
result_of_funct(x);
In order to expand the macro at compile time to 56 or 20, the compiler
would have to be able to see into the future to know what value the user
will enter. And if the program is going to be run more than once, with
different inputs typed by the user, then the only way to expand the
macro at compile time is to split the universe into two parallel
dimensions, each with their own version of the program and the user
input.
I suppose that is enough to let you know that a macro definition like
what you ask for is inherently impossible at compile time?
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).

The preprocessor is a one-pass device. You cannot create new
preprocessing instructions with macros unless you plan to compile your
source multiple times.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"The large yellow ships hung in the sky in exactly the same way that bricks
don't."
- Douglas Adams
 
B

BQ

"Joona I Palaste" <[email protected]> ha scritto nel messaggio
[CUT]
I suppose that is enough to let you know that a macro definition like
what you ask for is inherently impossible at compile time?

I agree with you.
But my issue is different (I believe).
Let say I have

#define A 100
#define B 0

#define FUNCT(x) #if (x>35) 56 #else 20 #endif /*a working version of it ;-) */

(...)

int main(....
{
.....
int c,d;

c=A; //should be c=56
d=B; //should be d=20;
}


This doesn't require knowledge of the future and can be safely expanded by the
preprocessor with:

.....
c=56;
d=20;
.....

The preprocessor is a one-pass device. You cannot create new
preprocessing instructions with macros

So I suppose I'll finish writing a small pre-preprocessor ... doh!
unless you plan to compile your
source multiple times.

Great! How can this be done?

Regards,

Marco Lazzaroni
 
C

Case

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,

I've read the discussion so far. I think your problem might
be solved by compiler optimization. Most modern compiler will
not generate any if-instructions for code like: 3 ? 23 : 20.
Also, many compilers have the ability to leave out never reached
code. So for

if (NEAR(0x1234))
FUNCT_NEAR(....);
else
FUNCT(.....);

only code for one of the two branches *could* be generated given
that NEAR(0x1234) can be evaluated at compiler (or sometimes even
link time).

Does this help?

Kees
 
D

Dik T. Winter

> #define FUNCT(x) #if (x>35) 56 #else 20 #endif /*a working version of it ;-) */

But (x > 35 ? 56 : 20) is a working version with a good optimising
compiler.
> c=A; //should be c=56
> d=B; //should be d=20; ....
> This doesn't require knowledge of the future and can be safely expanded by the
> preprocessor with:
> ....
> c=56;
> d=20;
> ....

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.
 
J

Joona I Palaste

BQ said:
"Joona I Palaste" <[email protected]> ha scritto nel messaggio
[CUT]
I suppose that is enough to let you know that a macro definition like
what you ask for is inherently impossible at compile time?
I agree with you.
But my issue is different (I believe).
Let say I have
#define A 100
#define B 0
#define FUNCT(x) #if (x>35) 56 #else 20 #endif /*a working version of it ;-) */

int main(....
{
....
int c,d;
c=A; //should be c=56
d=B; //should be d=20;
}
This doesn't require knowledge of the future and can be safely expanded by the
preprocessor with:
....
c=56;
d=20;
....

You know that, I know that, but C compilers don't. The compilers aren't
intelligent enough to think "outside of the box" and see that the above
code can be handled without knowledge of run-time operations. So what
you want is still impossible with the current version of C.
So I suppose I'll finish writing a small pre-preprocessor ... doh!
Great! How can this be done?

It's a bit difficult. I'm not sure myself how to do it. I had in mind
first preprocessing your code into an intermediate version and then
preprocessing it again. I don't know if there's a way to compile the
normal parts first and the preprocessed parts later.
 
C

Case

BQ said:
"Allan Bruce" <[email protected]> ha scritto nel messaggio
news:[email protected]...

[CUT}]


CMP x,value ;// compare x with value
JMPZN;// skip if the status flag of last was negative
GOTO xxx;// x is greater than value, so goto the given line of execution

so thats only 3 lines of assembly, which is probably about 6bytes +
sizeof(int)

Allan


Allan,
the real define I need is used about 500 times in the code, so this would be a large
waste of space (and cpu time).

In particular, that define is a bit access that is different depending on the location of
the byte (near, far) containing the bit I need to test/bit/set.
At compile time, I know if that particular byte is in near or in far memory.

Having defined

typedef struct {
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
} BOOL;

and

#define BIT(byte,bit) (*((BOOL*)&byte)).bit

Where bit can be b0,b1,b2...b7.

And so I can access a bit in the memory.
Compiling it, I get 2 ASM instructions.
Anyway if I use this definition, valid only for near memory:

#define BIT(byte,bit) (*((near BOOL*)&byte)).bit

...I would get 1 single ASM instruction.


So, provided that I have a way to determine AT COMPILE TIME if I am able to use this
second define (and I can) (let call this macro ISNEAR(byte)),
I would like to write something like this:

#define BIT(byte,bit) #if ISNEAR(byte) ( (*((near BOOL*)&byte)).bit ) #else (
(*((BOOL*)&byte)).bit ) #endif

How does ISNEAR() look like? What does it depend on? Do you know at
preprocessor-time if ISNEAR() is true/false? Have you tried all
compiler/linker options to see if you can get the required result (i.e.,
omitting not reached code or simplifying constant expressions)?

Kees
 
B

BQ

"Case" <[email protected]> ha scritto nel messaggio
[CUT]
I've read the discussion so far. I think your problem might
be solved by compiler optimization. Most modern compiler will
not generate any if-instructions for code like: 3 ? 23 : 20.
Also, many compilers have the ability to leave out never reached
code. So for

if (NEAR(0x1234))
FUNCT_NEAR(....);
else
FUNCT(.....);

only code for one of the two branches *could* be generated given
that NEAR(0x1234) can be evaluated at compiler (or sometimes even
link time).

Does this help?

Kees

Yes, Kees, you gave me a good idea. But I have to trust in my compiler (mcc18 from
microchip.com, for embedded microprocessors)...and I won't do that... even if it has a
'Unreachable code removal' switch (not sure if really always working :-O ) I'll give it a
try, you'll never know ;-)
I think that there must - or should - be a way to do this at compile time.
If the preprocessor doesn't support this, I think I'll write a small pre-preprocessor.

Regards,
Marco Lazzaroni
 
C

Case

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

I've read the discussion so far. I think your problem might
be solved by compiler optimization. Most modern compiler will
not generate any if-instructions for code like: 3 ? 23 : 20.
Also, many compilers have the ability to leave out never reached
code. So for

if (NEAR(0x1234))
FUNCT_NEAR(....);
else
FUNCT(.....);

only code for one of the two branches *could* be generated given
that NEAR(0x1234) can be evaluated at compiler (or sometimes even
link time).

Does this help?

Kees


Yes, Kees, you gave me a good idea. But I have to trust in my compiler (mcc18 from
microchip.com, for embedded microprocessors)...and I won't do that... even if it has a
'Unreachable code removal' switch (not sure if really always working :-O ) I'll give it a
try, you'll never know ;-)
I think that there must - or should - be a way to do this at compile time.
If the preprocessor doesn't support this, I think I'll write a small pre-preprocessor.

This is a reply to my cancelled message. I'm not yet convinced that
you might need a pre-preprocessor. Again, what does ISNEAR() look
like? I suppose trying another is not an option.

Kees
 

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