#define p

  • Thread starter Frank Silvermann
  • Start date
F

Frank Silvermann

#define q p

I must admit to a most elementary confusion. I have only ever used
#define to, in point of fact, #redefine . The above is standard. Is
the following:

#define UNNAMED_OS_32_LEAN_AND_MEAN

? frank
 
K

Keith Thompson

Frank Silvermann said:
#define q p

I must admit to a most elementary confusion. I have only ever used
#define to, in point of fact, #redefine . The above is standard. Is
the following:

#define UNNAMED_OS_32_LEAN_AND_MEAN

Yes. The syntax for a definition of an object-like macro (one that
doesn't take arguments) is:

# define identifier replacement-list new-line

The replacement-list can be empty. If it is, then any occurrence of
the identifier is replaced by nothing. Such an identifier is usually
used with "#ifdef" or "#if defined(...)".

Incidentally, your
#define q p
isn't what's normally called a redefinition. A redefinition is a
#define for something that's already been defined as a macro. It's
allowed only if the replacement-list is identical to the existing one.
 
F

Frank Silvermann

Keith said:
Yes. The syntax for a definition of an object-like macro (one that
doesn't take arguments) is:

# define identifier replacement-list new-line

The replacement-list can be empty. If it is, then any occurrence of
the identifier is replaced by nothing. Such an identifier is usually
used with "#ifdef" or "#if defined(...)".

Incidentally, your
#define q p
isn't what's normally called a redefinition. A redefinition is a
#define for something that's already been defined as a macro. It's
allowed only if the replacement-list is identical to the existing one.

Let me try the question from a different angle: when the preprocessor
hits the source in stage 1, what does it do besides deciding what is
#defined ?
 
J

jjf

Keith said:
Yes. The syntax for a definition of an object-like macro (one that
doesn't take arguments) is:

# define identifier replacement-list new-line

The replacement-list can be empty.

I can't find where the Standard allows the replacement-list to be
empty. In such cases, the Standard usually follows the term with a
suffix of 'opt' in the syntax summary, and it doesn't in this case. Nor
can I find any mention of an empty replacement-list is the discussion
of object-like macros.

I know that what you describe is how all C implementations I've used
work, but from a quick scan I can't see how the Standard allows it.
Could you explain how you derive this, please.
 
K

Keith Thompson

I can't find where the Standard allows the replacement-list to be
empty. In such cases, the Standard usually follows the term with a
suffix of 'opt' in the syntax summary, and it doesn't in this case. Nor
can I find any mention of an empty replacement-list is the discussion
of object-like macros.

I know that what you describe is how all C implementations I've used
work, but from a quick scan I can't see how the Standard allows it.
Could you explain how you derive this, please.

C99 6.10:

control-line:
...
# define identifier replacement-list new-line

...

replacement-list:
pp-tokens(opt)

(where "opt" is a subscript).

C90 6.8 has the same thing.
 
K

Keith Thompson

Frank Silvermann said:
Let me try the question from a different angle: when the preprocessor
hits the source in stage 1, what does it do besides deciding what is
#defined ?

I'm not sure what you mean. If by "stage 1" you mean "translation
phase 1", all that does is some character mapping and trigraph
replacement. Preprocessing directives aren't processed until phase 4.

Can you re-phrase the question, preferably with an example?
 
F

Frank Silvermann

Keith said:
I'm not sure what you mean. If by "stage 1" you mean "translation
phase 1", all that does is some character mapping and trigraph
replacement. Preprocessing directives aren't processed until phase 4.

Can you re-phrase the question, preferably with an example?
Yeah. What does the preprocessor do with:
#define SWAP(m, n) (tmp = m, m = n, n= tmp)
? This statement is different from
#define SOMETHING
, and according to the above, the preprocessor replaces SOMETHING with
nothing. (?)

The direction I'm headed with this is to wonder about the types of 'm'
and 'n'. frank
 
K

Keith Thompson

Frank Silvermann said:
Yeah. What does the preprocessor do with:
#define SWAP(m, n) (tmp = m, m = n, n= tmp)
?

This is a "function-like" macro. An invocation of it requires
arguments in parentheses. SWAP(foo, bar) is replaced by the
definition of SWAP, with each occurrence of m replaced by foo,
and each occurrence of n replaced by bar.
This statement is different from
#define SOMETHING
, and according to the above, the preprocessor replaces SOMETHING with
nothing. (?)
Right.

The direction I'm headed with this is to wonder about the types of 'm'
and 'n'. frank

They don't have types. Macro replacement just does textual
substitution (actually it works on tokens, but it's pretty much the
same thing). The preprocessor has no concept of types or expressions.
 
J

Joe Smith

This is a "function-like" macro. An invocation of it requires
arguments in parentheses. SWAP(foo, bar) is replaced by the
definition of SWAP, with each occurrence of m replaced by foo,
and each occurrence of n replaced by bar.
I agologize in advance for confusion with my newsreaders, the other one of
which is behaving badly despite having been killed and re-installed.
Anyways, am I right to think that if I have this macro, then I'm going to
want to have a 'tmp', 'm' and 'n' of the same type, and that this type could
be different depending on what is in scope during the SWAP?
But this amnesia comes after the #IFDEF's, probably right at the end of step
4?
They don't have types. Macro replacement just does textual
substitution (actually it works on tokens, but it's pretty much the
same thing). The preprocessor has no concept of types or expressions.
Given that a person is going to do fewer than ten thousand of these swaps,
and that whatever is passed by value isn't bulky, I wonder aloud as to the
style of it. joe
 
K

Keith Thompson

Joe Smith said:
I agologize in advance for confusion with my newsreaders, the other one of
which is behaving badly despite having been killed and re-installed.
Anyways, am I right to think that if I have this macro, then I'm going to
want to have a 'tmp', 'm' and 'n' of the same type, and that this type could
be different depending on what is in scope during the SWAP?

Right. This:

SWAP(foo, bar)

is *exactly* equivalent to this:

(tmp = foo, foo = bar, bar= tmp)

so exactly the same considerations apply.

Incidentally, it's generally safer to fully parenthesize each macro
argument in a macro definition:

#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)

It shouldn't matter for any reasonable invocation of SWAP(), but it's
easier to *always* use parentheses than to try to figure out when
they're not required (and force anyone reading and/or maintaining the
code to stop and think about it).
But this amnesia comes after the #IFDEF's, probably right at the end of step
4?

Yes, assuming that "step 4" means "translation phase 4".

Here's my usual example of preprocessor abuse:

#include <stdio.h>

#define SIX 1+5
#define NINE 8+1

int main(void)
{
printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
return 0;
}
 
F

Frank Silvermann

Keith said:
Right. This:

SWAP(foo, bar)

is *exactly* equivalent to this:

(tmp = foo, foo = bar, bar= tmp)

so exactly the same considerations apply.

Incidentally, it's generally safer to fully parenthesize each macro
argument in a macro definition:

#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)

It shouldn't matter for any reasonable invocation of SWAP(), but it's
easier to *always* use parentheses than to try to figure out when
they're not required (and force anyone reading and/or maintaining the
code to stop and think about it).


Yes, assuming that "step 4" means "translation phase 4".

Here's my usual example of preprocessor abuse:

#include <stdio.h>

#define SIX 1+5
#define NINE 8+1

int main(void)
{
printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
return 0;
}
Fun example. The fellow who was top-posting today wrote:
"Btw... nice use, of algebraic precedence (always nice to see)."
I didn't want to ruin his day and tell him that algebraists typically
work right to left and that telling left from right is the hardest thing
we do. Your example shows good form not just for a walking C
encyclopedia, but the next guy as well. frank
 
D

Dave Thompson

They don't have types. Macro replacement just does textual
substitution (actually it works on tokens, but it's pretty much the
same thing). The preprocessor has no concept of types or expressions.

<pedantic> Preprocessor _macros_ have no concept of types, or of
expressions beyond matching/nested parentheses.

Preprocessor #if and #elif do have expressions _almost_ the same as
constant (compile-time) expressions in the language, but types limited
to the largest integer types, long in C90 and intmax_t in C99.

- David.Thompson1 at worldnet.att.net
 

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

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,141
Latest member
BlissKeto
Top