Preprocessor - can it make conditional decisions

A

anon.asdf

Hello!

Can the proprocessor make conditional decisions. Here's an example of
the functionality (not standard C!)

#define PUT_BYTE(const_index, val) \
#preprocessor_if (const_index == 0) \
({ *(77) = (val); }) \
#preprocessor_else_if (const_index == 1) \
({ *(99) = (val); }) \
#preprocessor_end

Could the above snipped be done in C??

-anon.asdf
 
A

anon.asdf

Hello!

Can the proprocessor make conditional decisions. Here's an example of
the functionality (not standard C!)

#define PUT_BYTE(const_index, val) \
#preprocessor_if (const_index == 0) \
({ *(77) = (val); }) \
#preprocessor_else_if (const_index == 1) \
({ *(99) = (val); }) \
#preprocessor_end

Could the above snipped be done in C??

-anon.asdf

A better title would be:
"Can the proprocessor make conditional decisions in macros, based on
macro arguments"...

sorry about that...
 
R

Richard Tobin

Can the proprocessor make conditional decisions. Here's an example of
the functionality (not standard C!)

#define PUT_BYTE(const_index, val) \
#preprocessor_if (const_index == 0) \
({ *(77) = (val); }) \
#preprocessor_else_if (const_index == 1) \
({ *(99) = (val); }) \
#preprocessor_end

No. But in this particular case, if you just use an ordinary "if",
the compiler will be able to see that the condition is constant and
will probably generate the same code as if you had been able to do it
in the preprocessor. On the other hand, it may well give a warning
for a conditional with a constant condition.

-- Richard
 
C

Chris Dollin

A better title would be:
"Can the proprocessor make conditional decisions in macros, based on
macro arguments"...

No, it can't.

When did `({ *(99) = (val); })` become legal syntax? Is this some C99
thing I missed, or a proprietaryism I've been lucky to escape?
 
A

anon.asdf

When did `({ *(99) = (val); })` become legal syntax? Is this some C99
thing I missed, or a proprietaryism I've been lucky to escape?

My mistake!
({ *((int *)99) = (val); })
is what was meant.
Thanks!
 
C

Chris Dollin

My mistake!
({ *((int *)99) = (val); })
is what was meant.
Thanks!

(a) When did `({ *((int *)99) = (val); })` become legal syntax (fx:etc)?

(b) Presumably you know that casting an integer to a pointer and then
assigning through it is horribly unportable, and have Extremely
Good Reasons for juggling swords while dancing on a tightrope
blindfolded while a currently-unemployed nasal demon breaths
gentle flames over the knots.
 
A

Army1987

Hello!

Can the proprocessor make conditional decisions. Here's an example of
the functionality (not standard C!)

#define PUT_BYTE(const_index, val) \
#preprocessor_if (const_index == 0) \
({ *(77) = (val); }) \
#preprocessor_else_if (const_index == 1) \
({ *(99) = (val); }) \
#preprocessor_end

Could the above snipped be done in C??
#if CONST_INDEX == 0
#define PUT_BYTE(const_index, val) ({ *(77) = (val); })
#elif CONST_INDEX == 1
#define PUT_BYTE(const_index, val) ({ *(99) = (val); })
#endif

This can *not* do what you mean, because CONST_INDEX must be a
preprocessor constant (that's even stricter than a compile-time
constant: for example you can't use sizeof), if it is probably
you don't want to pass two arguments to the macro.
Try
#define PUT_BYTE(const_index, val) ({ *(const_index ? 99 : 77) \
= (val); })
if you know that const_index is either 0 or 1.
Btw the ({ and }) stuff isn't standard C.
 
A

Army1987

My mistake!
({ *((int *)99) = (val); })
is what was meant.
Thanks!
Putting a block in parentheses only makes sense in some extensions,
not in standard C.
 
A

Army1987

A better title would be:
"Can the proprocessor make conditional decisions in macros, based on
macro arguments"...

Try with
#define PUT_BYTE0 something
#define PUT_BYTE1 something_else
 
C

CBFalconer

Can the proprocessor make conditional decisions. Here's an example
of the functionality (not standard C!)

#define PUT_BYTE(const_index, val) \
#preprocessor_if (const_index == 0) \
({ *(77) = (val); }) \
#preprocessor_else_if (const_index == 1) \
({ *(99) = (val); }) \
#preprocessor_end

Could the above snipped be done in C??

Works better if you use the language correctly:

#if const_index == 0
# define PUT_BYTE(const_index, val) (whatever is legal)
#elsif const_index == 1
# define PUT_BYTE(const_index, val) (something else)
#endif
 
R

Ravishankar S

Army1987 said:
#if CONST_INDEX == 0
#define PUT_BYTE(const_index, val) ({ *(77) = (val); })
#elif CONST_INDEX == 1
#define PUT_BYTE(const_index, val) ({ *(99) = (val); })
#endif

This can *not* do what you mean, because CONST_INDEX must be a
preprocessor constant (that's even stricter than a compile-time
constant: for example you can't use sizeof), if it is probably
you don't want to pass two arguments to the macro.
Try
#define PUT_BYTE(const_index, val) ({ *(const_index ? 99 : 77) \
= (val); })
if you know that const_index is either 0 or 1.
Btw the ({ and }) stuff isn't standard C.
 
R

Ravishankar S

Assuming val is of type byte only, perhaps you can use inline functions..

static inline void __put_byte(const int index, unsigned char val) {
if(index == 0) {
...

} else if (index == 1) {



}
}

Even if you have val of many types then you use the GNU extension typeof()
( if you use GNU CC that is)

#define PUT_BYTE(const_index,val) {\
if(typeof(val) == typeof(int)) {\
__put_int();\
} else if(typeof(val) == typeof(float) ) {\
__put_float();\
} \

Regards,
Ravi
 
A

anon.asdf

C could have a better way of preprocessing, by allowing computations
on a META-Level, where code is not transformed to machine-code.
However, within this META-Level, one could specify which machine code
is actually desired.

#preprocessor_META_level_ON
...
#machine_code_begin
...
#machine_code_end
...
#preprocessor_META_level_OFF



Below there is an example of this idea!



Try with
#define PUT_BYTE0 something
#define PUT_BYTE1 something_else


I know of this, but I want to save writing out "millions" of lines, by
getting the preprocessor to figure out the pattern (on a META-Level),
instead of me having to mundanely hardcode a pattern:


/************** Example: nice to have *****************/
int regA;
#define MEM_MAP_A &regA;

int regB;
#define MEM_MAP_B &regB;


#define GO(val) \
#preprocessor_META_level_ON \
if (!(val % 3)) \
#machine_code_begin \
*((int *) MEM_MAP_A) = val \
#machine_code_end \
else \
#machine_code_begin \
*((int *) MEM_MAP_B) = val \
#machine_code_end \
#preprocessor_META_level_OFF \

/*
if the preprocessor catches a variable in the meta_level e.g.
{
int my_var;
GO(my_var);
}
then a compiler-error (or rather preprocessor-error) should result!
*/


//In the code I'll have:

{
GO(1);
//...
GO(876);
//...
GO(7987);
//...
GO(3);
//...
}

/************** end *****************/

This would be 4294967296 times better :) - (assuming val is a 4 byte
int)
than the following:



/************** Example: bitter reality *****************/
//...
#define GO_1 *((int *) MEM_MAP2) = 1
#define GO_2 *((int *) MEM_MAP2) = 2
#define GO_3 *((int *) MEM_MAP1) = 3
#define GO_4 *((int *) MEM_MAP2) = 4
#define GO_5 *((int *) MEM_MAP2) = 5
//...
#define GO_7987 *((int *) MEM_MAP2) = 7987

//many many lines above!

//In the code I'll have:

{
GO_1;
//...
GO_876;
//...
GO_7987;
//...
GO_3;
//...
}

/************** end *****************/



#define PUT_BYTE(const_index, val) ({ *(const_index ? 99 : 77) \
= (val); })
if you know that const_index is either 0 or 1.

Similar to your suggestion above, there'll be people who'll now say:
The compiler will resolve it for you - and that one could go and use
this:


#define GO(val) \
{ if (!(val % 3)) \
*((int *) MEM_MAP_A) = val; \
else \
*((int *) MEM_MAP_B) = val; \
}

But who knows what the compiler will do??? Maby it will NOT resolve it
and actually include the "if" in the machine code. Don't we want
guarantees??

Yes I could also write a program (special_generator.c) to generate a
header file (head.h) with the "millions" of preprocessor-lines I need,
but I'll just argue that it's confusing to have the generator source
(special_generator.c) in a different file, than it's generated result
(head.h)

The beauty of a Meta-Level, would be that the generator information is
not a seperate special C-file, but embedded in itself:
head.h includes a Meta-Level ...

And more importantly, programmers could have guarantees on what is
resolved and what is not resolved.
..
..
..

My main criticism here, is that C does not have a good method of
working on a Meta-Level.

Actually it's not a severe critisism - C is really great!
But it could still evolve, right?!

anon.asdf
 
A

anon.asdf

(a) When did `({ *((int *)99) = (val); })` become legal syntax (fx:etc)?

Hi Chris!

Here's a nice example that illustrates ({ ... }):


/*********({ ... })**********/
#include <stdio.h>

#define GET_OUT 'q'

#define PRE_COND \
({ c = getchar(); \
putchar(c); \
})

int main(void)
{
int c;
while (PRE_COND, c != GET_OUT); // 'q' and enter to exit
return 0;
}
/*********end*********

Regards,
Albert
 
A

anon.asdf

Hi all!

I just realized something really strange!

Try this code!

/************* test.c *********************/
#include <stdio.h>

#define GET_OUT 'q'

#define PRE_COND \
({ c = getchar(); \
putchar(c); \
})

int main(void)
{
int c;
while (PRE_COND, c != GET_OUT) {
printf("CHEERS");
}
return 0;
}

/**********************************/

a)
This works OK:

albert@aaa:~/ccc$ ./test
bbbq<Enter>
bCHEERSbCHEERSbCHEERSqalbert@aaa:~/ccc$

b)
albert@aaa:~/ccc$ ./test
b<Enter>
bCHEERS
CHEERSb<Enter>
bCHEERS
CHEERSb<Enter>
bCHEERS
CHEERSq<Enter>
qalbert@aaa:~/ccc$

Why does it print 2 CHEERS in a row??????

This is really confusing me. Is this a compiler error?
(gcc -v smiles at me and says:
gcc version 4.1.2)

Help!
 
A

anon.asdf

Hi all!

I just realized something really strange!

Try this code!

/************* test.c *********************/
#include <stdio.h>

#define GET_OUT 'q'

#define PRE_COND \
({ c = getchar(); \
putchar(c); \

})

int main(void)
{
int c;
while (PRE_COND, c != GET_OUT) {
printf("CHEERS");
}
return 0;

}

/**********************************/

a)
This works OK:

albert@aaa:~/ccc$ ./test
bbbq<Enter>
bCHEERSbCHEERSbCHEERSqalbert@aaa:~/ccc$

b)
albert@aaa:~/ccc$ ./test
b<Enter>
bCHEERS
CHEERSb<Enter>
bCHEERS
CHEERSb<Enter>
bCHEERS
CHEERSq<Enter>
qalbert@aaa:~/ccc$

Why does it print 2 CHEERS in a row??????

This is really confusing me. Is this a compiler error?
(gcc -v smiles at me and says:
gcc version 4.1.2)

Help!

Ahhh! Sorry , sorry no compiler error!
Doh! It's the <Enter>.

My huge mistake!
-Albert
 
C

CBFalconer

Ravishankar said:
Assuming val is of type byte only, perhaps you can use inline functions..

You are top-posting. Cease this if you want to have answers.

Please do not top-post. Your answer belongs after (or intermixed
with) the quoted material to which you reply, after snipping all
irrelevant material. See the following links:

--
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/> (taming google)
<http://members.fortunecity.com/nnqweb/> (newusers)
 
D

Dik T. Winter

>
> Ahhh! Sorry , sorry no compiler error!
> Doh! It's the <Enter>.

gcc -Wall -ansi -pedantic smiles at me and says:

@@P.c: In function `main':
@@P.c:14: warning: ANSI C forbids braced-groups within expressions
 
P

pete

Hello!

Can the proprocessor make conditional decisions.

An IOCCC entry in 1995,
solved the Towers of Hanoi, via the C pre-processor,
but I couldn't understand the code.
 
S

Stephen Sprunk

Hello!

Can the proprocessor make conditional decisions. Here's an example of
the functionality (not standard C!)

#define PUT_BYTE(const_index, val) \
#preprocessor_if (const_index == 0) \
({ *(77) = (val); }) \
#preprocessor_else_if (const_index == 1) \
({ *(99) = (val); }) \
#preprocessor_end

Could the above snipped be done in C??

Yes. The C way to do the above is:

#define PUT_BYTE(const_index, val) \
do { \
if (!const_index) { *(int*)77 = (val); } \
else { *(int *)99 = (val); } \
} while (0)

(Note that assumes val is of type int; modify the cast if it's some other
type. And, of course, that cast is inherently unportable for at least two
reasons.)

Of course, there's no need to use a macro in the first place; just make it a
function. In C99 (or various flavors of C89 with the extension), you may
want to make it an inline function if you're concerned about overhead.

S
 

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
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top