Topic: string-literal concatenation in #include directive?


Author: AllanW@my-dejanews.com
Date: 1998/06/09
Raw View
In article <357C14CF.7754F95C@acm.org>,
  Pete Becker <petebecker@acm.org> wrote:
>
> jkanze@otelo.ibmmail.com wrote:
> > But you can do token pasting in the invoked macro (although not in the
> > include declaration itself):
> >
> >     #define SYSINCLUDE(x)   <##x##.h>
> >     #include SYSINCLUDE(new)
>
> Yup. For some reason I had thought that the rules wer more restrictive
> than this. But they're not.
>  -- Pete

Shouldn't this work as well?
    #define SYSINCLUDE(x) <x##.h>
    #include SYSINCLUDE(new)
so that you're not trying to paste < and new into a single token?

As for the quoted version, I haven't tried this, but I'm guessing this:
    #define QUOTE "
    #define LOCALINCLUDE(x) QUOTE  x##.h  QUOTE
    // Or possibly          QUOTE##x##.h##QUOTE
    #include LOCALINCLUDE(myclass)
expands to #include "myclass.h" -- yes?

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/06/10
Raw View
AllanW@my-dejanews.com wrote:
> As for the quoted version, I haven't tried this, but I'm guessing
> this:
>     #define QUOTE "
>     #define LOCALINCLUDE(x) QUOTE  x##.h  QUOTE
>     // Or possibly          QUOTE##x##.h##QUOTE
>     #include LOCALINCLUDE(myclass)
> expands to #include "myclass.h" -- yes?

No.  The first #define is incorrect; a quote (") by itself is an
unterminated string constant (with an embedded newline).  I don't
think there's a way to do what you want with this example.  But do
you really need to do this?

-- David R. Tribble, david.tribble@noSPAM.central.beasys.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jkanze@otelo.ibmmail.com
Date: 1998/06/10
Raw View
In article <6ljm67$t6n$1@nnrp1.dejanews.com>,
  AllanW@my-dejanews.com wrote:
>
> In article <357C14CF.7754F95C@acm.org>,
>   Pete Becker <petebecker@acm.org> wrote:
> >
> > jkanze@otelo.ibmmail.com wrote:
> > > But you can do token pasting in the invoked macro (although not in the
> > > include declaration itself):
> > >
> > >     #define SYSINCLUDE(x)   <##x##.h>
> > >     #include SYSINCLUDE(new)
> >
> > Yup. For some reason I had thought that the rules wer more restrictive
> > than this. But they're not.
> >  -- Pete
>
> Shouldn't this work as well?
>     #define SYSINCLUDE(x) <x##.h>
>     #include SYSINCLUDE(new)
> so that you're not trying to paste < and new into a single token?

It's hard to say.  From the draft standard: "The method by which a sequence
of preprocessing tokens between a < and a > preprocessing token pair or a
pair of " characters is combined into a single header name preprocessing
token is implementation-defined."  Which doesn't really leave much hope
for portable code.

The form I proposed is the result of a long discussion some time back in
comp.std.c++, and was, if I remember correctly, the consensus as to the
best way of doing it.  I use it regularly, and it works with g++, Sun CC,
HP CC (the old one, at least), xlC and VC++.  Which is, all things
considered, a pretty small sampling.

> As for the quoted version, I haven't tried this, but I'm guessing this:
>     #define QUOTE "
>     #define LOCALINCLUDE(x) QUOTE  x##.h  QUOTE
>     // Or possibly          QUOTE##x##.h##QUOTE
>     #include LOCALINCLUDE(myclass)
> expands to #include "myclass.h" -- yes?

The replacement-list in a #define must consist of valid preprocessor tokens.
There is no token ", only a string literal.  Thus, the first #define is
illegal.  Note that this is NOT the case of a #include line; the
lexical scanning after the #include does NOT follow normal rules, and
in particular, a " does NOT start a string literal, but is a token
in its own right.  This is also the reason why the stringizing operator
(#) cannot be used -- it generates a single preprocessing token.

Of course, this reasoning also leads me to think that your proposal for
the <...> form is more correct than what I am currently using.  A strict
interpretation of the standard would not allow either: in the description
of the # include pp-tokens newline form, it says "If the directive resulting
after all replacements does not match one of the two previous forms, the
behavior is undefined."  Since the result of macro replacement is itself
a list of pp-tokens, and there is no pp-token which is a h-char-sequence,
the form is unusable.  (This is obviously not the intent, since if the
intent was that it be unusable, there are much clearer ways of saying it.
Even in standardise.)  My interpretation is that what was meant was that
the resulting token list should be converted into a character string and
be reinterpreted.  And from the above quoted line, how it is converted
into a character string is implementation defined:-(.

The purpose of the extra ## in my original suggestion is to ensure that
the conversion doesn't introduce any extra whitespace, which could
conceivably occur if the results of the macro expansion was not a single
token.  On the other hand, concerning ##: "If the result is not a valid
preprocessing  token, the behavior is undefined."  The result of <##whatever
is certainly not a valid preprocessing token.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Pete Becker <petebecker@acm.org>
Date: 1998/06/06
Raw View
Martin Fabian wrote:
>
> Is an ANSI-conforming compiler (or rather its preprocessor) required to
> do macro expansion plus string-literal concatenation in #include
> directives? That is, is
>
> #define ShiningPath "C:/Shine/"
> #include ShiningPath "File.h"
>
> required (guaranteed) to work?

No. The only use of macros that is required to work is this:

#define ShiningPathName "File.h"
#include ShiningPathName

Or, of course, a name in angle brackets instead of quotes. Other than
that, no macro expansion takes place in interpreting #include
directives.
 -- Pete
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jkanze@otelo.ibmmail.com
Date: 1998/06/08
Raw View
In article <35787E29.9099081C@acm.org>,
  Pete Becker <petebecker@acm.org> wrote:
>
> Martin Fabian wrote:
> >
> > Is an ANSI-conforming compiler (or rather its preprocessor) required to
> > do macro expansion plus string-literal concatenation in #include
> > directives? That is, is
> >
> > #define ShiningPath "C:/Shine/"
> > #include ShiningPath "File.h"
> >
> > required (guaranteed) to work?
>
> No. The only use of macros that is required to work is this:
>
> #define ShiningPathName "File.h"
> #include ShiningPathName
>
> Or, of course, a name in angle brackets instead of quotes. Other than
> that, no macro expansion takes place in interpreting #include
> directives.

String literal concatenation doesn't work anywhere in the preprocessor.
But you can do token pasting in the invoked macro (although not in the
include declaration itself):

    #define SYSINCLUDE(x)   <##x##.h>
    #include SYSINCLUDE(new)

With still another level of indirection, you can probably get the results
into double quotes, but I don't think that it is guaranteed to have the
desired results.  The result of the # operator is a character string
literal, which is not the same as the "q-char-sequence" required by
the include.  (For that matter, this argument may also hold for the <...>
form; the result of token pasting is a single token, and not the sequence
< h-char-sequence >.  But I seem to recall this point being discussed
in comp.std.c, with the results that most people thought that it should
work, and in fact, it did work with all compilers tried.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Pete Becker <petebecker@acm.org>
Date: 1998/06/08
Raw View
jkanze@otelo.ibmmail.com wrote:
>
> But you can do token pasting in the invoked macro (although not in the
> include declaration itself):
>
>     #define SYSINCLUDE(x)   <##x##.h>
>     #include SYSINCLUDE(new)

Yup. For some reason I had thought that the rules wer more restrictive
than this. But they're not.
 -- Pete
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Martin Fabian <fabian@control.chalmers.se>
Date: 1998/06/05
Raw View
Is an ANSI-conforming compiler (or rather its preprocessor) required to
do macro expansion plus string-literal concatenation in #include
directives? That is, is

#define ShiningPath "C:/Shine/"
#include ShiningPath "File.h"

required (guaranteed) to work?

--
Martin Fabian
------------------------------------------------------------------------
   email: fabian@control.chalmers.se |   Control Engineering Laboratory
     tel: +46 (0)31 772 37 16        |  Department of Signals & Systems
     fax: +46 (0)31 772 37 30        | Chalmers University of Technology
                                     |       S-412 96 Gothenburg
     http://www.s2.chalmers.se       |              Sweden
------------------------------------------------------------------------
Everyone is talking about real-time, but how real is time, really?


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]