Macro Substitution Help Request

M

Malcolm

Hi,

I have the following which fails with "disagreement in number of macro
arguments" when compiling with Imagecraft ICCAVR. Has anyone got any
ideas - its not vital but would make the code a lot nicer to read:

#define SET(x,y) (x |=(1<<y))
#define PIEZO PORTB,5


then in code it fails when I do:

SET(PIEZO);

The SET macro works when I do:

SET(PORTB,5);

Any help appreciated. I have trawled the newsgroups but cannot find
what I'm looking for.

Malcolm.
 
S

SM Ryan

# Hi,
#
# I have the following which fails with "disagreement in number of macro
# arguments" when compiling with Imagecraft ICCAVR. Has anyone got any
# ideas - its not vital but would make the code a lot nicer to read:
#
# #define SET(x,y) (x |=(1<<y))
# #define PIEZO PORTB,5
#
#
# then in code it fails when I do:
#
# SET(PIEZO);

The preprocessor is chunking it up as
define-name: SET
open-paren: (
argument: PIEZO
define-name: PIEZO
argument-list: empty
close-paren: )
and then doing the substitutions
define-name: SET
open-paren: (
argument: PORTB,5
define-value: PORTB,5
close-paren: )

Some preprocessors will rechunk after doing substitutions, but yours
apparently does not (nor is it required to). So it is setting the
entire first argument x of SET to "PORTB,5" and cannot find the
second argument.

# The SET macro works when I do:
#
# SET(PORTB,5);

This time the preprocessor is chunking it up as
define-name: SET
open-paren: (
argument: PORTB
comma: ,
argument: 5
close-paren: )

CPP is not a particularly powerful macro processor; others are available that
will handle this better. You might have something like M5 or sed available,
or you can do your own preprocessor.
 
T

Tim Rentsch

Malcolm said:
Hi,

I have the following which fails with "disagreement in number of macro
arguments" when compiling with Imagecraft ICCAVR. Has anyone got any
ideas - its not vital but would make the code a lot nicer to read:

#define SET(x,y) (x |=(1<<y))
#define PIEZO PORTB,5


then in code it fails when I do:

SET(PIEZO);

The SET macro works when I do:

SET(PORTB,5);

Any help appreciated. I have trawled the newsgroups but cannot find
what I'm looking for.

Here is something that may do something like what
you want:

#define SET(x,y) ((x) |= 1u<<(y))
#define PIEZO ( PORTB, 5 )
#define INVOKE(x) x

INVOKE( SET PIEZO );

It's not especially pretty, but it seems to permit
using PIEZO as an argument to SET.

Incidentally, the definition of the SET macro was
rewritten slightly for some style improvements.
Generally macro parameters should be enclosed
in parentheses inside of macro definitions.
 
R

Robert Gamble

Thanks for the reply. Food for thought..

Here's some more food for thought: Include some context when posting
followups people know what you are responding to.

Robert Gamble
 
T

Thad Smith

Malcolm said:
Hi,

I have the following which fails with "disagreement in number of macro
arguments" when compiling with Imagecraft ICCAVR. Has anyone got any
ideas - its not vital but would make the code a lot nicer to read:

#define SET(x,y) (x |=(1<<y))
#define PIEZO PORTB,5


then in code it fails when I do:

SET(PIEZO);

Others have explained the problem. The macro processing is more subtle
than many realize because of the distinct order in which substitution
and rescanning is done.

Here is a solution I have used for similar applications:

/* Demonstrate field extraction of complex macros */
#define SET(bi) (PORT bi |= 1u<<PBIT bi )
#define PORT(p,b) p /* extract port name */
#define PBIT(p,b) b /* extract bit number */
#define PIEZO (PORTB,5)
#define SOUND PIEZO /* demonstrates reassigning
** macro, which also works */

unsigned int PORTB;

int main(void) {
SET(PIEZO);
SET(SOUND);
return 0;
}

You write extraction macros to get the field within the compound that
you want. Using that technique, I have written a set of macros that can
be used to logically set or reset a specified port bit. Another
parameter of the signal definition macro is whether the signal is low
true or high true, so that I can define a macro SETTRUE, for example,
which looks at the encoding in the signal specification and decides
whether to set or clear the bit. Add more parameters and you can set
groups of bits, such as a keyboard row number, where the macro knows the
number of bits and the offset within the byte. Similar macros can be
used for testing input bits or reading input fields.

Other code that you might want to include in your macro is saving output
bytes/words in a "shadow" array, so that if you cannot read the output
port directly (as you apparently can in your example), it will combine
the new output bit(s) with the current value of other bits in the output
port.

The nice parts about writing such macros is that you can define your I/O
bit assignments IN ONE PLACE. If you change assignments, there is
only one place that needs to be changed. Since the operand of the
macros are usually compile-time constants, as in this example, the
compiler optimizes the result as if you had hard coded the port and bit
specifications.

Thad
 
M

Malcolm

How about this for food - if you have nothing useful to contribute then
piss off. People have spent time answering with useful info for which I
am very grateful. Frankly your the type of person that gives the
usegroups a bad name.

For anyone else I am posting using google which by default does not
include context. Bloody hell, all I was doing was saying thanks for the
reply, something that is far too rare.

Oh and for dickheads like Robert Gamble and co here is the context:
 
R

Robert Gamble

How about this for food - if you have nothing useful to contribute then
piss off.

I did contribute something useful, you're not.
People have spent time answering with useful info for which I am very
grateful.

And every one of them included context so that what they were replying to
was obvious.
Frankly your the type of person that gives the usegroups a bad name.

I'd argue that its people who post without taking the time to learn the
proper conventions and then blow a gasket when this is pointed out to
them.
For anyone else I am posting using google which by default does not
include context.

Yes, we know, google is broken. If you had been following this group for
any period of time before posting (something you should do before posting
to any group) you would have seen something like this (often found in
CBFalconer's signature):

"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on "show
options" at the top of the article, then click on the "Reply" at the
bottom of the article headers." - Keith Thompson

Your post needs to be able to stand on its own, you shouldn't assume that
everyone just finished reading the post you are replying to before reading
yours. Usenet is not an incredibly reliable medium and it is often the
case that followups, such as yours, make it to a news server before the
post you are responding to. It is also not rare for news readers to
screw up the order of posts and followups, Google Groups has a number of
problems in this area. If you include context, these things become
non-issues.
Bloody hell, all I was doing was saying thanks for the reply, something
that is far too rare.

I didn't say you shouldn't have but if you provided context it would be
easier to tell what you were responding to. I'm sorry I didn't sugar-coat
this for you but this concept is usually pointed out several times a
day and many of us, myself included, are getting tired of it.
Oh and for dickheads like Robert Gamble and co here is the context:

This type of behavior and flagrant disregard for basic etiquette is likely
to get your plonked by the regulars which would result in the loss of a
valuable resource for your future inqueries.

That's a start but it belongs before your corresponding response.

Robert Gamble
 
M

Martin Ambuhl

Malcolm said:
How about this for food - if you have nothing useful to contribute then
piss off.

He contributed; I can't see that you did.
People have spent time answering with useful info for which I
am very grateful. Frankly your the type of person that gives the
usegroups a bad name.

Frankly, you are in error. You're the kind of person who, if not reined
in, that can give a newsgroup a bad name.
For anyone else I am posting using google which by default does not
include context.

It does if you bother to learn to use it correctly.
Bloody hell, all I was doing was saying thanks for the
reply, something that is far too rare.

Cursing while explaining that you were being polite is at best incongruous.
Oh and for dickheads like Robert Gamble and co here is the context:

Cursing and name-calling gives up any chance you had of convincing
anyone that you *ever* were polite.
 
M

Malcolm

Seeing as you don't own the newsgroups in which I am posting (I would
say thats a fair bet) then frankly you have no right to police them.
Once again many thanks to the people who were willing to take the time
to post a useful reply. I would not have felt the need to flame Mr
Gamble if he had actually posted something worthwhile - instead of
living under the illusion that he owns the damn place.
 
R

Robert Gamble

Seeing as you don't own the newsgroups in which I am posting (I would
say thats a fair bet) then frankly you have no right to police them.
Once again many thanks to the people who were willing to take the time
to post a useful reply. I would not have felt the need to flame Mr
Gamble if he had actually posted something worthwhile - instead of
living under the illusion that he owns the damn place.

*PLONK*

Robert Gamble
 
M

Martin Ambuhl

Malcolm said:
Seeing as you don't own the newsgroups in which I am posting (I would
say thats a fair bet) then frankly you have no right to police them.

Because you refuse to post any context, you might be responding to
anyone. However, no one has claimed ownership; no one has engaged in
any policing; and there is no logical connection in any case between
ownership and the right to police. You posited false premises and then
imposed a non-logical assumption on them to reach a non sequitur. This
does not recommend you highly in a technical newsgroup.
Once again many thanks to the people who were willing to take the time
to post a useful reply. I would not have felt the need to flame Mr
Gamble if he had actually posted something worthwhile - instead of
living under the illusion that he owns the damn place.

If you felt "the need" to flame Mr Gamble, then you probably "need" a
baby rattle and someone to warm your bottle.
 
P

Peter Shaggy Haywood

Groovy hepcat Malcolm was jivin' on 8 Sep 2005 04:36:22 -0700 in
comp.lang.c.
Macro Substitution Help Request's a cool scene! Dig it!
I have the following which fails with "disagreement in number of macro
arguments" when compiling with Imagecraft ICCAVR. Has anyone got any
ideas - its not vital but would make the code a lot nicer to read:

#define SET(x,y) (x |=(1<<y))
#define PIEZO PORTB,5

then in code it fails when I do:

SET(PIEZO);

The SET macro is passed a single argument, PIEZO. This expands to
PORTB,5, but only *after* the SET macro has been expanded. So SET is
not getting PORTB,5 but PIEZO.
The SET macro works when I do:

SET(PORTB,5);

That surprises me greatly. It would expand to this:

(PORTB,5 |=(1<<5);

But, of course, that's an error, because it attempts to modify an
integer constant.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
I

Irrwahn Grausewitz

Groovy hepcat Malcolm was jivin' on 8 Sep 2005 04:36:22 -0700 in
comp.lang.c.
Macro Substitution Help Request's a cool scene! Dig it!


The SET macro is passed a single argument, PIEZO. This expands to
PORTB,5, but only *after* the SET macro has been expanded. So SET is
not getting PORTB,5 but PIEZO.


That surprises me greatly. It would expand to this:

(PORTB,5 |=(1<<5);

Umm, no. It expands to:

(Whatever_PORTB_was_defined_as |=(1<<5);
But, of course, that's an error, because it attempts to modify an
integer constant.

The OP didn't provide the definition of PORTB, but my best guess is
that substitution of PORTB results in a modifiable lvalue.

Best Regards
 
K

Keith Thompson

Malcolm said:
How about this for food - if you have nothing useful to contribute then
piss off. People have spent time answering with useful info for which I
am very grateful. Frankly your the type of person that gives the
usegroups a bad name.

For anyone else I am posting using google which by default does not
include context. Bloody hell, all I was doing was saying thanks for the
reply, something that is far too rare.

Oh and for dickheads like Robert Gamble and co here is the context:
[snip]

Robert Gamble was trying to offer you some useful advice, advice that,
if you followed it, would make it easier for the rest of us to help
you when you need it.

The groups.google.com interface is broken by default. Many of us have
repeatedly complained to them about this. I honestly don't know why
they haven't fixed it yet, and I don't know whether they ever will.
Fortunately, it does provide a way to post followups properly. The
method has been posted here hundreds of times.

Insulting someone who is trying to help you is, among other things,
unwise. It will make it much more difficult for you to get help in
the future. I'm sure many of the regulars have already killfiled you.
I don't use a killfile myself, but I'm less certainly inclined to help
you than I would have been before this.

Incidentally, someone going by the name "Malcolm" (no last name given)
has been a regular poster here for some time. He posts from
btinternet.com; you post with a gmail.com address. Am I correct in
assuming you're not the same person? If so, and if you're going to
continue posting here, you might consider including your last name in
your headers, or at least tweaking your handle so it's unambiguous.

Robert Gamble is right. You're wrong. Trust me on this. (Or don't,
but I happen to know what I'm talking about.)
 

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

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top