Which preprocessor is correct?

  • Thread starter Tomás Ó hÉilidhe
  • Start date
T

Tomás Ó hÉilidhe

If you have:


#define errno retrieve_errno_func()

#define SUBSYSTEM_INCLUDE(subsystem, file) <subsystem/include/file>


then what should happen when you do:


#include SUBSYSTEM_INCLUDE(posix, errno.h)

gcc2.95 pre-processes as intended, to:

#include <posix/include/errno.h>

gcc3.4 preprocessed to:

#include <posix/include/retrueve_errno_func()>

My guess is that gcc3.4 was the correct one, even though it didn't
produce the intended result.
 
F

fnegroni

Because errno has to be lvalue-modifyable.

errno = 0;

will not work when errno expands to

foobar() = 0;

And from the incomplete code snippet from the OP, what gave you that
information?

I can very easily write this complete example, using the OP's code
snippet:

#define retrieve_errno_func() *retrieve_errno_func_impl()

#define errno retrieve_errno_func()

int myerrno;

int *retrieve_errno_func_impl()
{
return &myerrno;
}

int
main(void)
{
errno = 2;
return 0;
}

Which will be preprocessed into:

int myerrno;

int *retrieve_errno_func_impl()
{
return &myerrno;
}

int
main(void)
{
*retrieve_errno_func_impl() = 2;
return 0;
}
 
J

Johannes Bauer

fnegroni said:
And from the incomplete code snippet from the OP, what gave you that
information?

Nothing - but *you* asked why it cannot be a modifyable lvalue.
*retrieve_errno_func_impl() = 2;

Dereferencing any non-const, non-void pointer yields a modifyable
lvalue, which is exactly what I said.

Regards,
Johannes
 
P

Peter Nilsson

Eric said:
What you've shown for gcc3.4 cannot possibly be right, because
an "i" has somehow transmuted to a "u" and a ".h" has vanished.
(I *wish* people would learn to copy-and-paste instead of polluting
their posts with typos ...)

But if the "u" is turned back to "i" and the ".h" is restored,
I believe gcc3.4 is correct (6.10.2p4). Note that

#include < posix / include / retrieve_errno_func ( ) . h >

would also be correct, because macro replacement works with tokens
(actually "preprocessing tokens"), not with text.

Which is why the "" form, generated via #, is better IMO. The rules
for
whitespace are much clearer.
You'll also note
that the way all these pp-tokens get combined into a single header
name is implementation-defined, hence a threat to portability.

True, but the #include pp-tokens directive was not exactly designed
with maximal portability in mind! Certainly no more than (say) the
system() function was.
 
V

vippstar

And from the incomplete code snippet from the OP, what gave you that
information?

I can very easily write this complete example, using the OP's code
snippet:

#define retrieve_errno_func() *retrieve_errno_func_impl()

And retrieve_errno_func() would be a function-like macro expanding to
a modifiable lvalue.
Notice my words:

vippstar said:
 
J

Johannes Bauer

Tomás Ó hÉilidhe said:
Please focus on the original topic of which preprocessor was correct.

Why should we? Although the topic has changed, the discourse is still
topical in c.l.c. - therefore I see no reason why one should not
digress. Most *really* interesting discussions evolve from something
which was not the primary question.

So unless I get paid for writing in c.l.c. I feel free to comment on
whatever appears to interest me :)

Kind regards,
Johannes
 
G

Giacomo Catenazzi

Eric said:
What you've shown for gcc3.4 cannot possibly be right, because
an "i" has somehow transmuted to a "u" and a ".h" has vanished.
(I *wish* people would learn to copy-and-paste instead of polluting
their posts with typos ...)

But if the "u" is turned back to "i" and the ".h" is restored,
I believe gcc3.4 is correct (6.10.2p4). Note that

#include < posix / include / retrieve_errno_func ( ) . h >

would also be correct, because macro replacement works with tokens
(actually "preprocessing tokens"), not with text. You'll also note
that the way all these pp-tokens get combined into a single header
name is implementation-defined, hence a threat to portability.

I don't agree. From section 6.4 and 6.4.7, the header-name is a
indivisible token, so it should not be splitt and substituted.

ciao
cate
 

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,952
Messages
2,570,111
Members
46,697
Latest member
python3bitcoin

Latest Threads

Top