Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > macros that build macros

Reply
Thread Tools

macros that build macros

 
 
Thant Tessman
Guest
Posts: n/a
 
      09-11-2007

Back before C++ templates, I was taught a trick whereby one built C
macros that built other C macros. I can't remember how the heck we did
it. The problem is that there seems to be no standard way to include a
'#' or '#define' in the output of a macro. The other problem is that we
might have been using some sort of non-standard preprocessor trick to do it.

Obliged if anyone can point me in the right direction or tell me what
I'm trying to do is impossible.

-thant
 
Reply With Quote
 
 
 
 
borophyll@gmail.com
Guest
Posts: n/a
 
      09-11-2007
On Sep 11, 11:08 am, Thant Tessman <(E-Mail Removed)> wrote:
> Back before C++ templates, I was taught a trick whereby one built C
> macros that built other C macros. I can't remember how the heck we did
> it. The problem is that there seems to be no standard way to include a
> '#' or '#define' in the output of a macro. The other problem is that we
> might have been using some sort of non-standard preprocessor trick to do it.
>
> Obliged if anyone can point me in the right direction or tell me what
> I'm trying to do is impossible.
>
> -thant


It is impossible, according to the standard (paragraph 3 of 6.10.3.4
"Rescanning and further replacement")

"The resulting completely macro-replaced preprocessing token sequence
is not processed
as a preprocessing directive even if it resembles one, but all pragma
unary operator
expressions within it are then processed as specified in 6.10.9
below."

In other words, you cannot create preprocessor directives using macro
replacement. Of course, the compiler you were using in the past may
have had a non-standard extension which may have allowed such
behaviour

Regards,
B

 
Reply With Quote
 
 
 
 
Jack Klein
Guest
Posts: n/a
 
      09-11-2007
On Mon, 10 Sep 2007 19:08:16 -0600, Thant Tessman
<(E-Mail Removed)> wrote in comp.lang.c:

>
> Back before C++ templates, I was taught a trick whereby one built C
> macros that built other C macros. I can't remember how the heck we did
> it. The problem is that there seems to be no standard way to include a
> '#' or '#define' in the output of a macro. The other problem is that we
> might have been using some sort of non-standard preprocessor trick to do it.
>
> Obliged if anyone can point me in the right direction or tell me what
> I'm trying to do is impossible.
>
> -thant


"borophyll" already gave you the standard answer, that you cannot
directly generate a macro to be replaced in the expansion of another
macro.

There are other ways, depending on what it is you are trying to do,
which you haven't made clear. Show us an example of the macro you
would like to generate, and the other macros that you would like to
use in the generation. It might be possible.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
Reply With Quote
 
robertwessel2@yahoo.com
Guest
Posts: n/a
 
      09-11-2007
On Sep 10, 8:08 pm, Thant Tessman <(E-Mail Removed)> wrote:
> Back before C++ templates, I was taught a trick whereby one built C
> macros that built other C macros. I can't remember how the heck we did
> it. The problem is that there seems to be no standard way to include a
> '#' or '#define' in the output of a macro. The other problem is that we
> might have been using some sort of non-standard preprocessor trick to do it.
>
> Obliged if anyone can point me in the right direction or tell me what
> I'm trying to do is impossible.



While it's not possible in general, sometimes people run C source code
through the preprocessor twice before the compiler proper. That way
any generated #defines in the first preprocessor pass get expanded in
the second.

There's no standard way of doing that, but many compilers have an
option to stop after the preprocessing phase and to emit that code.
Some compilers implement the preprocessor as a separate program, which
you can run manually. Again, all well outside the scope of the
standard.

 
Reply With Quote
 
borkhuis@gmail.com
Guest
Posts: n/a
 
      09-11-2007
On Sep 11, 3:08 am, Thant Tessman <(E-Mail Removed)> wrote:
> Back before C++ templates, I was taught a trick whereby one built C
> macros that built other C macros. I can't remember how the heck we did
> it. The problem is that there seems to be no standard way to include a
> '#' or '#define' in the output of a macro. The other problem is that we
> might have been using some sort of non-standard preprocessor trick to do it.
>
> Obliged if anyone can point me in the right direction or tell me what
> I'm trying to do is impossible.


As indicated by others it is not possible to do this using the
standard preprocessor and compiler, you need to run the preprocessor
more than once.

A preprocessor that I used for something like this is GPP (http://
en.nothingisreal.com/wiki/GPP), which is a general purpose
preprocessor. Next to the standard evaluation rules that CPP uses it
also defines a 2-pass evaluation. This is from the manual page:

#defeval x y
This acts in a similar way to #define, but the second argument y is
evaluated immediately. Since user macro definitions are also evaluated
each time they are called, this means that the macro y will undergo
two successive evaluations.

Kind regards,
Johan Borkhuis

 
Reply With Quote
 
Thant Tessman
Guest
Posts: n/a
 
      09-11-2007
I (Thant Tessman) wrote:

> Back before C++ templates, I was taught a trick whereby one built C
> macros that built other C macros. I can't remember how the heck we did
> it. [...]


My thanks to all who replied. For the curious, the basic form of what
I'm trying to do is this:

#define FOO(A,B) stuff

should produce another macro:

#define BAR_A_B(C) stuff

The macros produce code in support of type-safe inter-process message
passing routines.

This is definitely a situation where it would be inappropriate to
deviate from the standard, and the workaround is simple enough:

#define FOO(A,B) stuff
#define BAR(A,B,C) more stuff

The reason this solution is less desirable is that the latter allows for
errors that the former would catch. But it's workable.

Again, thanks for the replies.

-thant
 
Reply With Quote
 
Dave Hansen
Guest
Posts: n/a
 
      09-11-2007
On Sep 11, 7:24 am, Thant Tessman <(E-Mail Removed)> wrote:
[...]
> My thanks to all who replied. For the curious, the basic form of what
> I'm trying to do is this:
>
> #define FOO(A,B) stuff
>
> should produce another macro:
>
> #define BAR_A_B(C) stuff
>
> The macros produce code in support of type-safe inter-process message
> passing routines.
>
> This is definitely a situation where it would be inappropriate to
> deviate from the standard, and the workaround is simple enough:
>
> #define FOO(A,B) stuff
> #define BAR(A,B,C) more stuff
>
> The reason this solution is less desirable is that the latter allows for
> errors that the former would catch. But it's workable.


It's not really clear to me what you're trying to do. But I've used
sort of a backwards means of doing something similar. Consider the
following macros:

#define BIT(p,b) (b)

#define PORT(p,b) (PORT ## p)
#define PIN(p,b) (PIN ## p)
#define DDR(p,b) (DDR ## p)

#define MASK(b) (1 << (b))

#define Set_Port_Bit(p,b) ((p) |= MASK(b))
#define Clr_Port_Bit(p,b) ((p) &= ~MASK(b))
#define Tgl_Port_Bit(p,b) ((p) ^= MASK(b))

#define Get_Port_Bit(p,b) (((p) & MASK(b)) != 0)

#define Set_Output(io) Set_Port_Bit(PORT(io),BIT(io))
#define Reset_Output(io) Clr_Port_Bit(PORT(io),BIT(io))

#define Get_Input(io) Get_Port_Bit(PIN(io),BIT(io))

#define Tristate(io) Clr_Port_Bit(DDR(io),BIT(io))
#define Drive(io) Set_Port_Bit(DDR(io),BIT(io))

This was for an AVR microprocessor. There were for digital I/O ports,
a, B, C, and D. There were three I/O address for each digital I/O
port, PIN for reading input, PORT for writing output, and DDR (Data
Direction Register) to set each bit to be an input or an output. The
name of each register was appended with the port it referred to, e.g.,
PORTA, DDRB, PIND.

The macros above let me specify my output bits something like this

#define STATUS_LED A,7
#define SWITCH(n) D,(n+3) // switches on D3, D4, and D5

Then I could invoke the macros something like

Set_Output(STATUS_LED);
state = Get_Input(SWITCH(1));

If the hardware changes, and the status LED moved to port B, pin 3,
all I have to do is change the STATUS_LED definition to

#define STATUS_LED B,3

and everything works.

Perhaps you can adapt something like this.

Regards,

-=Dave

 
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
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
SWsoft Acronis Disk Director Suite 9.0 Build 508, Acronis OS Selector 8.0 Build 917, Acronis Partition Expert 2003 Build 292, Acronis Power Utilities 2004 Build 502, F-SECURE.ANTI vIRUS.PROXY v1.10.17.WINALL, F-SECURE.ANTI vIRUS v5.50.10260 for CITRI vvcd Computer Support 0 09-25-2004 01:38 AM
Explanation of macros; Haskell macros mike420@ziplip.com Python 80 11-07-2003 02:22 AM
Re: Explanation of macros; Haskell macros mike420@ziplip.com Python 5 11-01-2003 01:09 AM
Re: Explanation of macros; Haskell macros mike420@ziplip.com Python 1 10-07-2003 04:07 PM



Advertisments