Preprocessor eating backslashes??

O

Olе Streicher

Hi group,

In a program I want to compile, the preprocessor is used in an unusual
way: (some of the) #defines are protected with an underscore, then the C
preprocessor is called, and then the protection is removed.

The preprocessor is called on lines like:

---------8<----
_#define FOO \
BAR
---------8<----

which results (gcc 4.6.1) in

---------8<----
_#define FOO
BAR
---------8<----

Where is the backslash gone? Is this standard behaviour? And how can I
ensure that the backslash stays on its place?

Best regards

Ole
 
E

ec429

Where is the backslash gone? Is this standard behaviour? And how can I
ensure that the backslash stays on its place?
A backslash at the end of the line indicates line-continuation; that is,
backslash-newline is treated as (escaped) whitespace, and discarded.
Consequently,
_#define FOO \
BAR
is parsed as "_#define FOO BAR", and because "_#define" isn't a
preprocessing-token (and the \ isn't within a string), the cpp assumes
that the \\n is intertoken whitespace and thus
_#define FOO
BAR
and
_#define FOO BAR
are the same thing, similarly to how
int
i;
is the same thing as plain "int i;". That's why it thinks it safe to
just discard the backslash and leave the newline in place (many cpps try
to avoid doing too much that changes line numbers as it means they have
to emit LINE directives (if that's supported) or just break the
linenumbers in your error reports). If you want it to survive, you'll
have to escape it,
_#define FOO \\
BAR
which (I think) should work, though might not produce exactly what you
want; gcc 4.4.3's cpp turns it into "_#define FOO \BAR".
Why are you doing this, though? It doesn't seem like something that
would come up in normal preprocessor use (since backslash-newline is
treated as whitespace by the cc too); are you stringizing or
token-pasting, or just using the cpp as a general text macro processor
(don't do that!)?
-e
 
K

Keith Thompson

In a program I want to compile, the preprocessor is used in an unusual
way: (some of the) #defines are protected with an underscore, then the C
preprocessor is called, and then the protection is removed.

The preprocessor is called on lines like:

---------8<----
_#define FOO \
BAR
---------8<----

which results (gcc 4.6.1) in

---------8<----
_#define FOO
BAR
---------8<----

Where is the backslash gone? Is this standard behaviour? And how can I
ensure that the backslash stays on its place?

The only way I can think of to ensure that the backslash stays in place
is not to feed the file through the preprocessor.

The C standard doesn't guarantee that you can even invoke the
preprocessor separately, or that its output is text. Logically, the
output of the preprocessor is a sequence of preprocessor tokens.

Compilation is defined (in C99 5.1.1.2) as a sequence of 8 translation
phases (actually phase 8 is linking). In phase 2:

Each instance of a backslash character (\) immediately followed
by a new-line character is deleted, splicing physical source
lines to form logical source lines.

So I'd expect the output to be:

---------8<----
_#define FOO BAR
---------8<----

Experiment shows that "gcc -E" does behave as you describe, at least
with the version I have. But other compilers (including an earlier
version of gcc) produce a single line.

Why don't you just comment out the "#define" with // rather than using
an underscore?
 
E

ec429

Why don't you just comment out the "#define" with // rather than using
an underscore?
I think he wants to preserve the #define intact so that it can be
restored later. Running //#define through the cpp may disappear it
(does on gcc 4.4.3, anyway).
-e
 
O

Olе Streicher

ec429 said:
Why are you doing this, though? It doesn't seem like something that would
come up in normal preprocessor use (since backslash-newline is treated as
whitespace by the cc too); are you stringizing or token-pasting, or just using
the cpp as a general text macro processor (don't do that!)?

This is not my code. The code in question is from

<http://starlink.jach.hawaii.edu/starlink/AST>

where they build a common header file from the header files in the
source. During this process, they want to preprocess some statements,
but leave the #define s intact.

I am trying to bring this to a modern gcc now.

Best regards

Ole
 
E

ec429

This is not my code. The code in question is from

<http://starlink.jach.hawaii.edu/starlink/AST>

where they build a common header file from the header files in the
source. During this process, they want to preprocess some statements,
but leave the #define s intact.

I am trying to bring this to a modern gcc now.
I think you can tell gcc's cpp to only perform some parts of
preprocessing; either replace the _ with // and use -C, or perhaps try
-fdirectives-only. In any case, read "man cpp", and experiment.
Also see if you can find a way to build the common header file without
using cpp; it seems like it's the wrong tool for the job.
-e
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top