Preprocessor eating backslashes??

Discussion in 'C Programming' started by Olе Streicher, Jan 11, 2012.

  1. 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
     
    Olе Streicher, Jan 11, 2012
    #1
    1. Advertising

  2. Olе Streicher

    ec429 Guest

    On 11/01/12 09:23, Olе Streicher wrote:
    > 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
    --
    'sane', adj.: see 'unimaginative'
    on the web - http://jttlov.no-ip.org
     
    ec429, Jan 11, 2012
    #2
    1. Advertising

  3. (Olе Streicher) writes:
    > 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?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 11, 2012
    #3
  4. Olе Streicher

    ec429 Guest

    On 11/01/12 10:29, Keith Thompson wrote:
    > 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
    --
    'sane', adj.: see 'unimaginative'
    on the web - http://jttlov.no-ip.org
     
    ec429, Jan 11, 2012
    #4
  5. ec429 <> writes:
    > On 11/01/12 09:23, Olе Streicher wrote:
    >> Where is the backslash gone? Is this standard behaviour? And how can I
    >> ensure that the backslash stays on its place?

    > 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
     
    Olе Streicher, Jan 11, 2012
    #5
  6. Olе Streicher

    ec429 Guest

    On 11/01/12 12:58, Olе Streicher wrote:
    > 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
    --
    'sane', adj.: see 'unimaginative'
    on the web - http://jttlov.no-ip.org
     
    ec429, Jan 11, 2012
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Cronus
    Replies:
    1
    Views:
    681
    Paul Mensonides
    Jul 15, 2004
  2. rossum

    cin is eating my output

    rossum, Oct 5, 2004, in forum: C++
    Replies:
    4
    Views:
    594
    rossum
    Oct 9, 2004
  3. Bryan

    popen eating quotes?

    Bryan, Aug 3, 2003, in forum: Python
    Replies:
    8
    Views:
    474
    Christopher Koppler
    Aug 4, 2003
  4. ewan

    4DOM eating all my memory

    ewan, Feb 1, 2004, in forum: Python
    Replies:
    1
    Views:
    356
    John J. Lee
    Feb 2, 2004
  5. Per B. Sederberg
    Replies:
    5
    Views:
    348
    Robert Kern
    Jan 22, 2007
Loading...

Share This Page