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

Macro Substitution Help Request

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

Nov 15 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
"Malcolm" <ma**********@gmail.com> wrote:
# 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.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
I hope it feels so good to be right. There's nothing more
exhilarating pointing out the shortcomings of others, is there?
Nov 15 '05 #2

P: n/a
Thanks for the reply. Food for thought..

Nov 15 '05 #3

P: n/a
"Malcolm" <ma**********@gmail.com> writes:
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.
Nov 15 '05 #4

P: n/a
On Thu, 08 Sep 2005 08:30:07 -0700, Malcolm wrote:
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
Nov 15 '05 #5

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

Nov 15 '05 #6

P: n/a
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:
Here's some more food for thought: Include some context when posting
followups people know what you are responding to. Robert Gamble


Nov 15 '05 #7

P: n/a
On Sat, 10 Sep 2005 14:48:44 -0700, Malcolm wrote:
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.
Here's some more food for thought: Include some context when posting
followups people know what you are responding to.

Robert Gamble


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

Robert Gamble
Nov 15 '05 #8

P: n/a
Malcolm wrote:
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.
Nov 15 '05 #9

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

Nov 15 '05 #10

P: n/a
On Sat, 10 Sep 2005 16:17:54 -0700, Malcolm wrote:
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
Nov 15 '05 #11

P: n/a
Malcolm wrote:
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.
Nov 15 '05 #12

P: n/a
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"?
Nov 15 '05 #13

P: n/a
ph******@alphalink.com.au.NO.SPAM (Peter "Shaggy" Haywood) wrote:
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);


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
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc frequent answers: http://benpfaff.org/writings/clc
Nov 15 '05 #14

P: n/a
"Malcolm" <ma**********@gmail.com> writes:
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.)

--
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.
Nov 15 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.