By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,041 Members | 1,734 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,041 IT Pros & Developers. It's quick & easy.

Preprocessor - can it make conditional decisions

P: n/a
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

Aug 10 '07 #1
Share this Question
Share on Google+
36 Replies


P: n/a
In article <11*********************@m37g2000prh.googlegroups. com>,
<an*******@gmail.comwrote:
>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
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Aug 10 '07 #2

P: n/a
On Aug 10, 2:47 pm, Chris Dollin <chris.dol...@hp.comwrote:
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!

Aug 10 '07 #3

P: n/a
an*******@gmail.com wrote:
On Aug 10, 2:47 pm, Chris Dollin <chris.dol...@hp.comwrote:
>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!
(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.

--
Chris "DON'T PANIC!" Dollin

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

Aug 10 '07 #4

P: n/a
On Fri, 10 Aug 2007 05:36:24 -0700, anon.asdf wrote:
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.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 10 '07 #5

P: n/a
On Fri, 10 Aug 2007 06:04:05 -0700, anon.asdf wrote:
On Aug 10, 2:47 pm, Chris Dollin <chris.dol...@hp.comwrote:
>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!
Putting a block in parentheses only makes sense in some extensions,
not in standard C.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 10 '07 #6

P: n/a
an*******@gmail.com wrote:
>
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

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Aug 10 '07 #7

P: n/a

"Army1987" <ar******@NOSPAM.itwrote in message
news:pa****************************@NOSPAM.it...
On Fri, 10 Aug 2007 05:36:24 -0700, anon.asdf wrote:
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.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 10 '07 #8

P: n/a
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

"CBFalconer" <cb********@yahoo.comwrote in message
news:46***************@yahoo.com...
an*******@gmail.com wrote:

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

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Aug 10 '07 #9

P: n/a
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!

On Aug 10, 4:06 pm, Army1987 <army1...@NOSPAM.itwrote:
On Fri, 10 Aug 2007 05:44:22 -0700, anon.asdf wrote:
#define PUT_BYTE(const_index, val) \
#preprocessor_if (const_index == 0) \
({ *(77) = (val); }) \
#preprocessor_else_if (const_index == 1) \
({ *(99) = (val); }) \
#preprocessor_end
"Can the proprocessor make conditional decisions in macros, based on
macro arguments"...

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

Aug 10 '07 #10

P: n/a
On Aug 10, 3:09 pm, Chris Dollin <chris.dol...@hp.comwrote:
>
(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

Aug 10 '07 #11

P: n/a
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!

Aug 10 '07 #12

P: n/a
On Aug 10, 6:38 pm, anon.a...@gmail.com wrote:
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

Aug 10 '07 #13

P: n/a
Ravishankar S wrote:
>
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)

--
Posted via a free Usenet account from http://www.teranews.com

Aug 10 '07 #14

P: n/a
In article <11**********************@x40g2000prg.googlegroups .coman*******@gmail.com writes:
On Aug 10, 6:38 pm, anon.a...@gmail.com wrote:
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>.
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

--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Aug 10 '07 #15

P: n/a
an*******@gmail.com wrote:
>
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.

--
pete
Aug 10 '07 #16

P: n/a
<an*******@gmail.comwrote in message
news:11*********************@m37g2000prh.googlegro ups.com...
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

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Aug 11 '07 #17

P: n/a
On Fri, 10 Aug 2007 19:18:55 -0500, Stephen Sprunk wrote:
<an*******@gmail.comwrote in message
news:11*********************@m37g2000prh.googlegro ups.com...
>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)
Any reasons for use the ugly do while (0) trick when there is
a way to write it as an expression? What if I want to use it
as the third expression in the guard of a for loop? IMO, this
(except when necessary) is even worse than using a function.

#define PUT_BYTE(const_index, val) \
( *(int *)((const_index) ? 99 : 77) = (val) )
(Note that it always evaluates each argument exactly once.)
Or
int PUT_BYTE(int const_index, int val)
{
if (const_index) {
return *(int *)99 = val;
} else {
return *(int *)77 = val;
}
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.
Right.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 11 '07 #18

P: n/a
On Fri, 10 Aug 2007 10:06:59 -0400, CBFalconer wrote:
an*******@gmail.com wrote:
>>
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
You meant elif?
# define PUT_BYTE(const_index, val) (something else)
Hmm. If const_index is a macro expanding to 1, the above becomes
# define PUT_BYTE(0, val) (something else)
#endif
I think the OP was trying to have a macro in which
PUT_BYTE(0, val) expanded to ((something)(val))
and PUT_BYTE(1, foo) expanded to ((sth_else)(foo))
I don't think it is possible in standard C, but, since the first
argument is known at preprocessing time, one could simplily use
a PUT_BYTE0 macro and a PUT_BYTE1 macro.

--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 11 '07 #19

P: n/a
On Fri, 10 Aug 2007 16:13:42 +0000, anon.asdf wrote:
On Aug 10, 3:09 pm, Chris Dollin <chris.dol...@hp.comwrote:
>>
(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); \
})
This is not standard C, it is a GNU extension. Try
#define PRE_COND (c = getchar(), putchar(c))

--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 11 '07 #20

P: n/a
Army1987 <ar******@nospam.itwrote:
On Fri, 10 Aug 2007 10:06:59 -0400, CBFalconer wrote:
an*******@gmail.com wrote:
>
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
You meant elif?
# define PUT_BYTE(const_index, val) (something else)
Hmm. If const_index is a macro expanding to 1, the above becomes
# define PUT_BYTE(0, val) (something else)
#endif
I think the OP was trying to have a macro in which
PUT_BYTE(0, val) expanded to ((something)(val))
and PUT_BYTE(1, foo) expanded to ((sth_else)(foo))
I don't think it is possible in standard C,
Consider ## operator. It *is* possible. And you don't really want to do
it... ;).

Let's *try* to do it:
#define PUT_BYTE_0 sth
#define PUT_BYTE_1 sth_else

#define PUT_BYTE_EXPANDED(__x, __y) \
((PUT_BYTE_ ## __x)(__y))

#define PUT_BYTE(__x, __y) PUT_BYTE_EXPANDED(__x, __y)

but, since the first
argument is known at preprocessing time, one could simplily use
a PUT_BYTE0 macro and a PUT_BYTE1 macro.
Sometimes you can't. Consider function with parameter in it's name (you
can't use parameter, cause you have no register available) configured at
compile time.

M.

PS. I leave discovering PUT_BYTE_EXPANDED usage reasons as an exercise ;).
M.
Aug 11 '07 #21

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Ravishankar S wrote:
>>
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)
Back in the killfile you go. And get your signatures sorted out before
you lecture other people on posting styles.
Aug 11 '07 #22

P: n/a
"Army1987" <ar******@NOSPAM.itwrote in message
news:pa****************************@NOSPAM.it...
On Fri, 10 Aug 2007 19:18:55 -0500, Stephen Sprunk wrote:
>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)

Any reasons for use the ugly do while (0) trick when there is
a way to write it as an expression? What if I want to use it
as the third expression in the guard of a for loop? IMO, this
(except when necessary) is even worse than using a function.

#define PUT_BYTE(const_index, val) \
( *(int *)((const_index) ? 99 : 77) = (val) )
It didn't occur to me to use the trinary operator on the left side of an
assignment expression; that's probably an improvement, though I consider it
less readable and you should end up with the same code generated.
(Note that it always evaluates each argument exactly once.)
It's better in that respect.
Or
int PUT_BYTE(int const_index, int val)
{
if (const_index) {
return *(int *)99 = val;
} else {
return *(int *)77 = val;
}
Evil; functions should not be in upper case.

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Aug 11 '07 #23

P: n/a
On 11 Aug., 13:09, Marcin Wolcendorf <wolce...@friko2.onet.plwrote:
....
>
Consider ## operator. It *is* possible. And you don't really want to do
it... ;).

Let's *try* to do it:
#define PUT_BYTE_0 sth
#define PUT_BYTE_1 sth_else

#define PUT_BYTE_EXPANDED(__x, __y) \
((PUT_BYTE_ ## __x)(__y))

#define PUT_BYTE(__x, __y) PUT_BYTE_EXPANDED(__x, __y)
but, since the first
argument is known at preprocessing time, one could simplily use
a PUT_BYTE0 macro and a PUT_BYTE1 macro.

Sometimes you can't. Consider function with parameter in it's name (you
can't use parameter, cause you have no register available) configured at
compile time.

M.

PS. I leave discovering PUT_BYTE_EXPANDED usage reasons as an exercise ;).
M.
Hi Marcin!

I've tested it with
/*************/
#include <stdio.h>

#define PUT_BYTE_0(val) printf("0: %d\n", val)
#define PUT_BYTE_1(val) printf("1: %d\n", val)

#define PUT_BYTE(__x, __y) (PUT_BYTE_ ## __x(__y))

int main(void)
{
PUT_BYTE(0, 8);
PUT_BYTE(1, 9);
return 0;
}
/*************/

and it works nicely:

(I don't think we need PUT_BYTE_EXPANDED)

But this is just luck, that it's such a simple example!
How would you do the following:
/************** 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 *****************/

????????????
It can probably be done, but the header file with it's preprocessor
lines will be huge. Probably just as huge as

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

//many many lines above!

//In the code I'll have:

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

}

/************** end *****************/
The reality is that the preprocessor is not turing complete if a
program is preprocessed only once. (Ref: http://www.ioccc.org/2001/herrmann1.hint)

But a Meta-Level would make it turing complete, right? Refer to:
http://groups.google.de/group/comp.l...4e79644f7befd?

-Albert

Aug 12 '07 #24

P: n/a
On Sun, 12 Aug 2007 05:31:19 -0700, anon.asdf wrote:
The reality is that the preprocessor is not turing complete if a
program is preprocessed only once. (Ref: http://www.ioccc.org/2001/herrmann1.hint)

But a Meta-Level would make it turing complete, right? Refer to:
http://groups.google.de/group/comp.l...4e79644f7befd?
That's what the compiler is for.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 12 '07 #25

P: n/a
On Aug 12, 2:39 pm, Army1987 <army1...@NOSPAM.itwrote:
On Sun, 12 Aug 2007 05:31:19 -0700, anon.asdf wrote:
The reality is that the preprocessor is not turing complete if a
program is preprocessed only once. (Ref:http://www.ioccc.org/2001/herrmann1.hint)
But a Meta-Level would make it turing complete, right? Refer to:
http://groups.google.de/group/comp.l...4e79644f7befd?

That's what the compiler is for.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower
No! The compiler is there to generate machine code from C.

It should not be clouded by Meta-information like bit-width
calculations etc. all of which belong firmly to the preprocessor.

Though nice things can be done with the preprocessor, it is
unfortunately not powerful enough to allow one to really do things on
a meta-level.

Things like bit-width calculations etc. should really be done on a
Meta-Level, since the output is then a fixed bit-width, or a fixed C-
code segment:

I hate writing things like:

#define AAA 1<<8

int a = AAA;

because how do I know what the compiler is going to do, without
checking the generated asm, or machine code?

I'll rather write:
#define AAA 256 /* 1<<8 */

but I don't like it. This is where a Meta-Level would come in handy:

#define AAA \
#META_level( 1<<8 )

//or

#define BIT_WIDTH 8
#define AAA \
#META_level( 1<<BIT_WIDTH )

The Meta-Level guarantees that this is resolved.

On the otherhand, perhaps I've now just written a lot of junk, since
perhaps every compiler out there will simplify and resolve constants,
constant expressions, conditionals with constants, etc.

I still think my modulo-3 example:
http://groups.google.com/group/comp....9a3452cb74c4c?
is interesting though.

?
-Albert

Aug 12 '07 #26

P: n/a
On 11 Aug., 02:18, "Stephen Sprunk" <step...@sprunk.orgwrote:
#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.
But what if I make it a function which evaluates only constants and
returns only constants. In other words the function is only there
during preprocessing and compiler-resolution and -optimization.

Will an inline function guarantee that no superfluous code-bits will
sit in the generated machine code???

Example:

static inline int go(const int index, int val) {
if(index == 0) {
*((int *)77) = val;
} else {
*((int *)77) = val;
}
}

int main(void)
{
go(0, 1);
go(1, 3);

int a;
// calculations with a...
go(a, 8);

}
If all conditionals in the inline are resolved during preprocessing,
compiler-resolution/optimization, then thats nice.

The machine code should only have one conditional for
go(a, 8)
since it is not known before hand, what a will be

Albert

Aug 12 '07 #27

P: n/a
<an*******@gmail.comwrote in message
news:11**********************@w3g2000hsg.googlegro ups.com...
On 11 Aug., 02:18, "Stephen Sprunk" <step...@sprunk.orgwrote:
>#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.

But what if I make it a function which evaluates only constants and
returns only constants. In other words the function is only there
during preprocessing and compiler-resolution and -optimization.

Will an inline function guarantee that no superfluous code-bits will
sit in the generated machine code???
That's the whole point of inlining. Basically, you get all the performance
and overhead savings of using macros with all the safety and (most of the)
flexibility of functions.
Example:

static inline int go(const int index, int val) {
if(index == 0) {
*((int *)77) = val;
} else {
*((int *)77) = val;
}
}

int main(void)
{
go(0, 1);
go(1, 3);

int a;
// calculations with a...
go(a, 8);

}
If all conditionals in the inline are resolved during preprocessing,
compiler-resolution/optimization, then thats nice.

The machine code should only have one conditional for
go(a, 8)
since it is not known before hand, what a will be
Any decent compiler will do that with the appropriate optimizations enabled.
Many will even do it without the function being declared inline, as long as
the function's definition is visible. If your compiler doesn't do this, get
a new one. This has been a standard feature of C compilers ever since C++
made inlining so critical.

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Aug 12 '07 #28

P: n/a
"Stephen Sprunk" <st*****@sprunk.orgwrites:
[...]
Any decent compiler will do that with the appropriate optimizations
enabled. Many will even do it without the function being declared
inline, as long as the function's definition is visible. If your
compiler doesn't do this, get a new one. This has been a standard
feature of C compilers ever since C++ made inlining so critical.
For a loose definition of "standard". As I'm sure you know, the C90
standard doesn't define the 'inline' keyword (though it certainly
permits inlining as an optimization). C99 has the 'inline' keyword,
but it's only a hint, similar to 'register'. A conforming but
low-quality C99 compiler could simply ignore it, or a clever compiler
could ignore it and make its own decisions about which functions to
inline.

If you mean that support for inlining (with or without the keyword) is
a common feature of C compilers because many of them share code with
C++ compilers, you may well be right.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 12 '07 #29

P: n/a
On Sun, 12 Aug 2007 13:35:21 -0500, "Stephen Sprunk" wrote:
>anon wrote in message
news:11**********************@w3g2000hsg.googlegr oups.com...
>On 11 Aug., 02:18, "Stephen Sprunk" <step...@sprunk.orgwrote:
>>#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.

But what if I make it a function which evaluates only constants and
returns only constants. In other words the function is only there
during preprocessing and compiler-resolution and -optimization.

Will an inline function guarantee that no superfluous code-bits will
sit in the generated machine code???

That's the whole point of inlining. Basically, you get all the performance
and overhead savings of using macros with all the safety and (most of the)
flexibility of functions.
>Example:

static inline int go(const int index, int val) {
if(index == 0) {
*((int *)77) = val;
} else {
*((int *)77) = val;
}
}

int main(void)
{
go(0, 1);
go(1, 3);

int a;
// calculations with a...
go(a, 8);

}
If all conditionals in the inline are resolved during preprocessing,
compiler-resolution/optimization, then thats nice.

The machine code should only have one conditional for
go(a, 8)
since it is not known before hand, what a will be

Any decent compiler will do that with the appropriate optimizations enabled.
Many will even do it without the function being declared inline,
i not agree;
if i declare a big function not inline and the compiler inline it =>
the exe size (or the size of some loop) can become too big for the
good use from cpu
>as long as
the function's definition is visible. If your compiler doesn't do this, get
a new one. This has been a standard feature of C compilers ever since C++
made inlining so critical.
Aug 13 '07 #30

P: n/a
an*******@gmail.com wrote:
On Aug 10, 3:09 pm, Chris Dollin <chris.dol...@hp.comwrote:
>>
(a) When did `({ *((int *)99) = (val); })` become legal syntax (fx:etc)?

Hi Chris!

Here's a nice example that illustrates ({ ... }):
When did `({ ... })` become legal standard C syntax (fx:etc)?

--
Chris "usually it's worked by now" Dollin

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

Aug 13 '07 #31

P: n/a
On Mon, 13 Aug 2007 08:55:36 +0200, ¬a\/b wrote:
On Sun, 12 Aug 2007 13:35:21 -0500, "Stephen Sprunk" wrote:
>>anon wrote in message
news:11**********************@w3g2000hsg.googleg roups.com...
>>static inline int go(const int index, int val) {
[snip]
>>}
If all conditionals in the inline are resolved during preprocessing,
compiler-resolution/optimization, then thats nice.

The machine code should only have one conditional for
go(a, 8)
since it is not known before hand, what a will be

Any decent compiler will do that with the appropriate optimizations enabled.
Many will even do it without the function being declared inline,

i not agree;
if i declare a big function not inline and the compiler inline it =>
the exe size (or the size of some loop) can become too big for the
good use from cpu
Any decent compiler will do that only if it understands that it is
worth the trouble. Also, with some compilers you can choose
whether to optimize for space or for time (e.g -Os for gcc).
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 13 '07 #32

P: n/a
On Sun, 12 Aug 2007 14:58:33 +0000, anon.asdf wrote:
On Aug 12, 2:39 pm, Army1987 <army1...@NOSPAM.itwrote:
>On Sun, 12 Aug 2007 05:31:19 -0700, anon.asdf wrote:
The reality is that the preprocessor is not turing complete if a
program is preprocessed only once. (Ref:http://www.ioccc.org/2001/herrmann1.hint)
But a Meta-Level would make it turing complete, right? Refer to:
http://groups.google.de/group/comp.l...4e79644f7befd?

That's what the compiler is for.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

No! The compiler is there to generate machine code from C.

It should not be clouded by Meta-information like bit-width
calculations etc. all of which belong firmly to the preprocessor.

Though nice things can be done with the preprocessor, it is
unfortunately not powerful enough to allow one to really do things on
a meta-level.

Things like bit-width calculations etc. should really be done on a
Meta-Level, since the output is then a fixed bit-width, or a fixed C-
code segment:

I hate writing things like:

#define AAA 1<<8
Add parentheses (1<<8) or there might be great surprises when you
use it in a more complicated expression.
int a = AAA;

because how do I know what the compiler is going to do, without
checking the generated asm, or machine code?
1<<8 is a constant integer expression, so it is *very* unlikely to
be actually computed at runtime.
I'll rather write:
#define AAA 256 /* 1<<8 */

but I don't like it. This is where a Meta-Level would come in handy:

#define AAA \
#META_level( 1<<8 )

//or

#define BIT_WIDTH 8
You have CHAR_BIT defined in <limits.h>.
#define AAA \
#META_level( 1<<BIT_WIDTH )
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Aug 13 '07 #33

P: n/a
an*******@gmail.com wrote:
>
On Aug 10, 3:09 pm, Chris Dollin <chris.dol...@hp.comwrote:

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

Hi Chris!

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

/*********({ ... })**********/
What, the comment?
#include <stdio.h>

#define GET_OUT 'q'

#define PRE_COND \
({ c = getchar(); \
putchar(c); \
})
That's no good. That doesn't compile.
Should be:
#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;
}
--
pete
Aug 13 '07 #34

P: n/a
Army1987 wrote:
¬a\/b wrote:
.... snip ...
>
>i not agree; if i declare a big function not inline and the
compiler inline it the exe size (or the size of some loop) can
become too big for the good use from cpu

Any decent compiler will do that only if it understands that it
is worth the trouble. Also, with some compilers you can choose
whether to optimize for space or for time (e.g -Os for gcc).
a\/b is a known troll. Ignore it.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Aug 14 '07 #35

P: n/a
Hi,

an*******@gmail.com wrote:
On 11 Aug., 13:09, Marcin Wolcendorf <wolce...@friko2.onet.plwrote:
...

PS. I leave discovering PUT_BYTE_EXPANDED usage reasons as an exercise ;).
M.

Hi Marcin!

I've tested it with
/*************/
#include <stdio.h>

#define PUT_BYTE_0(val) printf("0: %d\n", val)
#define PUT_BYTE_1(val) printf("1: %d\n", val)

#define PUT_BYTE(__x, __y) (PUT_BYTE_ ## __x(__y))

int main(void)
{
PUT_BYTE(0, 8);
PUT_BYTE(1, 9);
return 0;
}
/*************/

and it works nicely:

(I don't think we need PUT_BYTE_EXPANDED)
As long, as 0 and 1 are numbers, not defines. If they are '#define'd,
you'll need expansion.

Regards,

M.W.

Aug 14 '07 #36

P: n/a
On Sat, 11 Aug 2007 09:18:27 -0500, "Stephen Sprunk"
<st*****@sprunk.orgwrote:
"Army1987" <ar******@NOSPAM.itwrote in message
news:pa****************************@NOSPAM.it...
On Fri, 10 Aug 2007 19:18:55 -0500, Stephen Sprunk wrote:
#define PUT_BYTE(const_index, val) \
do { \
if (!const_index) { *(int*)77 = (val); } \
else { *(int *)99 = (val); } \
} while (0)
(versus)
#define PUT_BYTE(const_index, val) \
( *(int *)((const_index) ? 99 : 77) = (val) )

It didn't occur to me to use the trinary operator on the left side of an
assignment expression; that's probably an improvement, though I consider it
less readable and you should end up with the same code generated.
Aside: it's officially the 'conditional' operator and commonly called
'ternary', but I've never heard it called 'trinary'.
(Note that it always evaluates each argument exactly once.)

It's better in that respect.
No, they're the same. The if-else version _evaluates_ only one
occurrence of (val), although it's _written_ twice -- and thus
expanded twice, but expansion by itself isn't a problem, only
execution of those expanded instances.

I personally like the ?: version as it better captures the semantic
similarity, and perhaps even better something like:
* (int*) (int[]){77,99} [idx] = val;
or more legibly
* (int*) addrs [idx] = val
where addrs is arranged to be in scope (most simply global)
as something like static const int addrs [] = {77,99};

But the if-else version is definitely valid -- if storing through
those pointer values is, which applies to all approaches.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Aug 26 '07 #37

This discussion thread is closed

Replies have been disabled for this discussion.