Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #71419 > unrolled thread

C++ preprocessor and multi-line string literals

Started byPaavo Helde <myfirstname@osa.pri.ee>
First post2020-01-16 17:37 +0200
Last post2020-01-22 12:03 +0000
Articles 20 on this page of 26 — 10 participants

Back to article view | Back to comp.lang.c++


Contents

  C++ preprocessor and multi-line string literals Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-16 17:37 +0200
    Re: C++ preprocessor and multi-line string literals Öö Tiib <ootiib@hot.ee> - 2020-01-16 09:46 -0800
      Re: C++ preprocessor and multi-line string literals Manfred <noname@add.invalid> - 2020-01-16 22:49 +0100
        Re: C++ preprocessor and multi-line string literals Öö Tiib <ootiib@hot.ee> - 2020-01-16 14:43 -0800
          Re: C++ preprocessor and multi-line string literals Manfred <invalid@add.invalid> - 2020-01-17 01:24 +0100
            Re: C++ preprocessor and multi-line string literals Öö Tiib <ootiib@hot.ee> - 2020-01-16 16:38 -0800
              Re: C++ preprocessor and multi-line string literals Manfred <invalid@add.invalid> - 2020-01-17 03:27 +0100
    Re: C++ preprocessor and multi-line string literals legalize+jeeves@mail.xmission.com (Richard) - 2020-01-16 20:07 +0000
    Re: C++ preprocessor and multi-line string literals Juha Nieminen <nospam@thanks.invalid> - 2020-01-20 13:53 +0000
      Re: C++ preprocessor and multi-line string literals Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-20 18:31 +0200
      Re: C++ preprocessor and multi-line string literals Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-20 18:19 +0100
        Re: C++ preprocessor and multi-line string literals Juha Nieminen <nospam@thanks.invalid> - 2020-01-21 08:24 +0000
          Re: C++ preprocessor and multi-line string literals boltar@nowhere.org - 2020-01-21 16:43 +0000
            Re: C++ preprocessor and multi-line string literals Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-21 19:25 +0200
              Re: C++ preprocessor and multi-line string literals boltar@nowhere.org - 2020-01-22 09:58 +0000
                Re: C++ preprocessor and multi-line string literals guinness.tony@gmail.com - 2020-01-22 02:11 -0800
                  Re: C++ preprocessor and multi-line string literals boltar@nowhere.org - 2020-01-22 10:24 +0000
                  Re: C++ preprocessor and multi-line string literals James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-23 22:25 -0500
                Re: C++ preprocessor and multi-line string literals Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-22 13:28 +0200
                  Re: C++ preprocessor and multi-line string literals boltar@nowhere.org - 2020-01-22 12:07 +0000
                    Re: C++ preprocessor and multi-line string literals Öö Tiib <ootiib@hot.ee> - 2020-01-22 05:33 -0800
                      Re: C++ preprocessor and multi-line string literals boltar@nowhere.org - 2020-01-22 16:03 +0000
                        Re: C++ preprocessor and multi-line string literals Öö Tiib <ootiib@hot.ee> - 2020-01-22 10:50 -0800
                          Re: C++ preprocessor and multi-line string literals boltar@nowhere.org - 2020-01-23 09:22 +0000
                    Re: C++ preprocessor and multi-line string literals Manfred <noname@add.invalid> - 2020-01-22 18:59 +0100
                Re: C++ preprocessor and multi-line string literals Juha Nieminen <nospam@thanks.invalid> - 2020-01-22 12:03 +0000

Page 1 of 2  [1] 2  Next page →


#71419 — C++ preprocessor and multi-line string literals

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2020-01-16 17:37 +0200
SubjectC++ preprocessor and multi-line string literals
Message-ID<qvpvvf$h2p$1@dont-email.me>
In C++ there is a preprocessor step which logically comes first and 
prepares the preprocessed source consisting of remaining tokens. 
However, preprocessor is line-based, so it ought to conflict with the 
multi-line string literals:

#include <iostream>

#if 1

int main() {
	const char* test = R"__(

#else

     )__";
	std::cout << test;
}

#endif

Obviously C++ compilers supporting C++11 are able to cope with that and 
handle the '#else' line as part of the string literal. My question is 
more about how they were able to standardize this behavior? Is there 
still a logically separate preprocessor step or not?

By googling I also find some EBNF formal syntax descriptions for C++, 
but these are different for the preprocessor and for the actual C++ 
language. With presence of multi-line string literals, is it even 
possible to provide a self-consistent EBNF formal syntax for the C++ 
preprocessor?

[toc] | [next] | [standalone]


#71420

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-16 09:46 -0800
Message-ID<92fc27c6-1146-4820-8bb3-54075c5b9fa4@googlegroups.com>
In reply to#71419
On Thursday, 16 January 2020 17:37:31 UTC+2, Paavo Helde  wrote:
> In C++ there is a preprocessor step which logically comes first and 
> prepares the preprocessed source consisting of remaining tokens. 
> However, preprocessor is line-based, so it ought to conflict with the 
> multi-line string literals:
> 
> #include <iostream>
> 
> #if 1
> 
> int main() {
> 	const char* test = R"__(
> 
> #else
> 
>      )__";
> 	std::cout << test;
> }
> 
> #endif
> 
> Obviously C++ compilers supporting C++11 are able to cope with that and 
> handle the '#else' line as part of the string literal. My question is 
> more about how they were able to standardize this behavior? Is there 
> still a logically separate preprocessor step or not?
> 
> By googling I also find some EBNF formal syntax descriptions for C++, 
> but these are different for the preprocessor and for the actual C++ 
> language. With presence of multi-line string literals, is it even 
> possible to provide a self-consistent EBNF formal syntax for the C++ 
> preprocessor?

[lex.phases]1.1.
| Physical source file characters are mapped, in an implementation-defined 
| manner, to the basic source character set (introducing new-line 
| characters for end-of-line indicators) if necessary. The set of 
| physical source file characters accepted is implementation-defined. Any 
| source file character not in the basic source character set (5.3) is 
| replaced by the universal-character-name that designates that 
| character. An implementation may use any internal encoding, so long 
| as an actual extended character encountered in the source file, and 
| the same extended character expressed in the source file as a 
| universal-charactername (e.g., using the \uXXXX notation), are 
| handled equivalently except where this replacement is reverted (5.4) 
| in a *raw* *string* *literal*.

So the raw string literal is already a token of very first translation
step. Preprocessing takes place in step 4. By that time it has been
string literal for 3 steps already.

[toc] | [prev] | [next] | [standalone]


#71426

FromManfred <noname@add.invalid>
Date2020-01-16 22:49 +0100
Message-ID<qvqloc$1ami$1@gioia.aioe.org>
In reply to#71420
On 1/16/2020 6:46 PM, Öö Tiib wrote:
> On Thursday, 16 January 2020 17:37:31 UTC+2, Paavo Helde  wrote:
>> In C++ there is a preprocessor step which logically comes first and
>> prepares the preprocessed source consisting of remaining tokens.
>> However, preprocessor is line-based, so it ought to conflict with the
>> multi-line string literals:
>>
>> #include <iostream>
>>
>> #if 1
>>
>> int main() {
>> 	const char* test = R"__(
>>
>> #else
>>
>>       )__";
>> 	std::cout << test;
>> }
>>
>> #endif
>>
>> Obviously C++ compilers supporting C++11 are able to cope with that and
>> handle the '#else' line as part of the string literal. My question is
>> more about how they were able to standardize this behavior? Is there
>> still a logically separate preprocessor step or not?
>>
>> By googling I also find some EBNF formal syntax descriptions for C++,
>> but these are different for the preprocessor and for the actual C++
>> language. With presence of multi-line string literals, is it even
>> possible to provide a self-consistent EBNF formal syntax for the C++
>> preprocessor?
> 
> [lex.phases]1.1.
> | Physical source file characters are mapped, in an implementation-defined
> | manner, to the basic source character set (introducing new-line
> | characters for end-of-line indicators) if necessary. The set of
> | physical source file characters accepted is implementation-defined. Any
> | source file character not in the basic source character set (5.3) is
> | replaced by the universal-character-name that designates that
> | character. An implementation may use any internal encoding, so long
> | as an actual extended character encountered in the source file, and
> | the same extended character expressed in the source file as a
> | universal-charactername (e.g., using the \uXXXX notation), are
> | handled equivalently except where this replacement is reverted (5.4)
> | in a *raw* *string* *literal*.
> 
> So the raw string literal is already a token of very first translation
> step. Preprocessing takes place in step 4. By that time it has been
> string literal for 3 steps already.
> 

(Using n4820.pdf)
I think the reference in here of a string literal is a forward reference 
(to section 5.4 [lex.pptoken]) and it only applies to handling of 
universal-character-names, it does not define string literals yet.

However, step 3 of [lex.phases] says: "The source file is decomposed 
into preprocessing tokens (5.4)".
Preprocessing tokens are defined in [lex.pptoken] (section 5.4 in 
n4820), and the list includes "string-literal" (specifically, it is 
defined at p3.1).
The following step 4 then executes preprocessing directives.

So, yes string literals are processed before preprocessing directives, 
but one step earlier, not three.

[toc] | [prev] | [next] | [standalone]


#71432

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-16 14:43 -0800
Message-ID<6d8cd72d-32d0-43e2-8be9-e6119b44c985@googlegroups.com>
In reply to#71426
On Thursday, 16 January 2020 23:49:14 UTC+2, Manfred  wrote:
> On 1/16/2020 6:46 PM, Öö Tiib wrote:
> > On Thursday, 16 January 2020 17:37:31 UTC+2, Paavo Helde  wrote:
> >> In C++ there is a preprocessor step which logically comes first and
> >> prepares the preprocessed source consisting of remaining tokens.
> >> However, preprocessor is line-based, so it ought to conflict with the
> >> multi-line string literals:
> >>
> >> #include <iostream>
> >>
> >> #if 1
> >>
> >> int main() {
> >> 	const char* test = R"__(
> >>
> >> #else
> >>
> >>       )__";
> >> 	std::cout << test;
> >> }
> >>
> >> #endif
> >>
> >> Obviously C++ compilers supporting C++11 are able to cope with that and
> >> handle the '#else' line as part of the string literal. My question is
> >> more about how they were able to standardize this behavior? Is there
> >> still a logically separate preprocessor step or not?
> >>
> >> By googling I also find some EBNF formal syntax descriptions for C++,
> >> but these are different for the preprocessor and for the actual C++
> >> language. With presence of multi-line string literals, is it even
> >> possible to provide a self-consistent EBNF formal syntax for the C++
> >> preprocessor?
> > 
> > [lex.phases]1.1.
> > | Physical source file characters are mapped, in an implementation-defined
> > | manner, to the basic source character set (introducing new-line
> > | characters for end-of-line indicators) if necessary. The set of
> > | physical source file characters accepted is implementation-defined. Any
> > | source file character not in the basic source character set (5.3) is
> > | replaced by the universal-character-name that designates that
> > | character. An implementation may use any internal encoding, so long
> > | as an actual extended character encountered in the source file, and
> > | the same extended character expressed in the source file as a
> > | universal-charactername (e.g., using the \uXXXX notation), are
> > | handled equivalently except where this replacement is reverted (5.4)
> > | in a *raw* *string* *literal*.
> > 
> > So the raw string literal is already a token of very first translation
> > step. Preprocessing takes place in step 4. By that time it has been
> > string literal for 3 steps already.
> > 
> 
> (Using n4820.pdf)
> I think the reference in here of a string literal is a forward reference 
> (to section 5.4 [lex.pptoken]) and it only applies to handling of 
> universal-character-names, it does not define string literals yet.
> 
> However, step 3 of [lex.phases] says: "The source file is decomposed 
> into preprocessing tokens (5.4)".
> Preprocessing tokens are defined in [lex.pptoken] (section 5.4 in 
> n4820), and the list includes "string-literal" (specifically, it is 
> defined at p3.1).
> The following step 4 then executes preprocessing directives.
> 
> So, yes string literals are processed before preprocessing directives, 
> but one step earlier, not three.

Are you suggesting what are the raw string literals should be
re-decided in later steps? 

[toc] | [prev] | [next] | [standalone]


#71435

FromManfred <invalid@add.invalid>
Date2020-01-17 01:24 +0100
Message-ID<qvqusg$io2$1@gioia.aioe.org>
In reply to#71432
On 1/16/20 11:43 PM, Öö Tiib wrote:
> On Thursday, 16 January 2020 23:49:14 UTC+2, Manfred  wrote:
>> On 1/16/2020 6:46 PM, Öö Tiib wrote:
>>> On Thursday, 16 January 2020 17:37:31 UTC+2, Paavo Helde  wrote:
>>>> In C++ there is a preprocessor step which logically comes first and
>>>> prepares the preprocessed source consisting of remaining tokens.
>>>> However, preprocessor is line-based, so it ought to conflict with the
>>>> multi-line string literals:
>>>>
>>>> #include <iostream>
>>>>
>>>> #if 1
>>>>
>>>> int main() {
>>>> 	const char* test = R"__(
>>>>
>>>> #else
>>>>
>>>>        )__";
>>>> 	std::cout << test;
>>>> }
>>>>
>>>> #endif
>>>>
>>>> Obviously C++ compilers supporting C++11 are able to cope with that and
>>>> handle the '#else' line as part of the string literal. My question is
>>>> more about how they were able to standardize this behavior? Is there
>>>> still a logically separate preprocessor step or not?
>>>>
>>>> By googling I also find some EBNF formal syntax descriptions for C++,
>>>> but these are different for the preprocessor and for the actual C++
>>>> language. With presence of multi-line string literals, is it even
>>>> possible to provide a self-consistent EBNF formal syntax for the C++
>>>> preprocessor?
>>>
>>> [lex.phases]1.1.
>>> | Physical source file characters are mapped, in an implementation-defined
>>> | manner, to the basic source character set (introducing new-line
>>> | characters for end-of-line indicators) if necessary. The set of
>>> | physical source file characters accepted is implementation-defined. Any
>>> | source file character not in the basic source character set (5.3) is
>>> | replaced by the universal-character-name that designates that
>>> | character. An implementation may use any internal encoding, so long
>>> | as an actual extended character encountered in the source file, and
>>> | the same extended character expressed in the source file as a
>>> | universal-charactername (e.g., using the \uXXXX notation), are
>>> | handled equivalently except where this replacement is reverted (5.4)
>>> | in a *raw* *string* *literal*.
>>>
>>> So the raw string literal is already a token of very first translation
>>> step. Preprocessing takes place in step 4. By that time it has been
>>> string literal for 3 steps already.
>>>
>>
>> (Using n4820.pdf)
>> I think the reference in here of a string literal is a forward reference
>> (to section 5.4 [lex.pptoken]) and it only applies to handling of
>> universal-character-names, it does not define string literals yet.
>>
>> However, step 3 of [lex.phases] says: "The source file is decomposed
>> into preprocessing tokens (5.4)".
>> Preprocessing tokens are defined in [lex.pptoken] (section 5.4 in
>> n4820), and the list includes "string-literal" (specifically, it is
>> defined at p3.1).
>> The following step 4 then executes preprocessing directives.
>>
>> So, yes string literals are processed before preprocessing directives,
>> but one step earlier, not three.
> 
> Are you suggesting what are the raw string literals should be
> re-decided in later steps?
> 
> 

No, "what are the raw string literals" is "decided" in step 3, and not 
in step 1.
I suggest you re-read step 1, more carefully.

[toc] | [prev] | [next] | [standalone]


#71437

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-16 16:38 -0800
Message-ID<43ff905d-bd29-468c-94df-db0b51665983@googlegroups.com>
In reply to#71435
On Friday, 17 January 2020 02:25:04 UTC+2, Manfred  wrote:
> On 1/16/20 11:43 PM, Öö Tiib wrote:
> > On Thursday, 16 January 2020 23:49:14 UTC+2, Manfred  wrote:
> >> On 1/16/2020 6:46 PM, Öö Tiib wrote:
> >>> On Thursday, 16 January 2020 17:37:31 UTC+2, Paavo Helde  wrote:
> >>>> In C++ there is a preprocessor step which logically comes first and
> >>>> prepares the preprocessed source consisting of remaining tokens.
> >>>> However, preprocessor is line-based, so it ought to conflict with the
> >>>> multi-line string literals:
> >>>>
> >>>> #include <iostream>
> >>>>
> >>>> #if 1
> >>>>
> >>>> int main() {
> >>>> 	const char* test = R"__(
> >>>>
> >>>> #else
> >>>>
> >>>>        )__";
> >>>> 	std::cout << test;
> >>>> }
> >>>>
> >>>> #endif
> >>>>
> >>>> Obviously C++ compilers supporting C++11 are able to cope with that and
> >>>> handle the '#else' line as part of the string literal. My question is
> >>>> more about how they were able to standardize this behavior? Is there
> >>>> still a logically separate preprocessor step or not?
> >>>>
> >>>> By googling I also find some EBNF formal syntax descriptions for C++,
> >>>> but these are different for the preprocessor and for the actual C++
> >>>> language. With presence of multi-line string literals, is it even
> >>>> possible to provide a self-consistent EBNF formal syntax for the C++
> >>>> preprocessor?
> >>>
> >>> [lex.phases]1.1.
> >>> | Physical source file characters are mapped, in an implementation-defined
> >>> | manner, to the basic source character set (introducing new-line
> >>> | characters for end-of-line indicators) if necessary. The set of
> >>> | physical source file characters accepted is implementation-defined. Any
> >>> | source file character not in the basic source character set (5.3) is
> >>> | replaced by the universal-character-name that designates that
> >>> | character. An implementation may use any internal encoding, so long
> >>> | as an actual extended character encountered in the source file, and
> >>> | the same extended character expressed in the source file as a
> >>> | universal-charactername (e.g., using the \uXXXX notation), are
> >>> | handled equivalently except where this replacement is reverted (5.4)
> >>> | in a *raw* *string* *literal*.
> >>>
> >>> So the raw string literal is already a token of very first translation
> >>> step. Preprocessing takes place in step 4. By that time it has been
> >>> string literal for 3 steps already.
> >>>
> >>
> >> (Using n4820.pdf)
> >> I think the reference in here of a string literal is a forward reference
> >> (to section 5.4 [lex.pptoken]) and it only applies to handling of
> >> universal-character-names, it does not define string literals yet.
> >>
> >> However, step 3 of [lex.phases] says: "The source file is decomposed
> >> into preprocessing tokens (5.4)".
> >> Preprocessing tokens are defined in [lex.pptoken] (section 5.4 in
> >> n4820), and the list includes "string-literal" (specifically, it is
> >> defined at p3.1).
> >> The following step 4 then executes preprocessing directives.
> >>
> >> So, yes string literals are processed before preprocessing directives,
> >> but one step earlier, not three.
> > 
> > Are you suggesting what are the raw string literals should be
> > re-decided in later steps?
> > 
> > 
> 
> No, "what are the raw string literals" is "decided" in step 3, and not 
> in step 1.
> I suggest you re-read step 1, more carefully.

Maybe I am confused indeed. Can we compose raw string literals
using \u0052 <- 'R' in step 1 for later steps? 

[toc] | [prev] | [next] | [standalone]


#71438

FromManfred <invalid@add.invalid>
Date2020-01-17 03:27 +0100
Message-ID<qvr61u$1h74$1@gioia.aioe.org>
In reply to#71437
On 1/17/20 1:38 AM, Öö Tiib wrote:
> On Friday, 17 January 2020 02:25:04 UTC+2, Manfred  wrote:
>> On 1/16/20 11:43 PM, Öö Tiib wrote:
>>> On Thursday, 16 January 2020 23:49:14 UTC+2, Manfred  wrote:
>>>> On 1/16/2020 6:46 PM, Öö Tiib wrote:
>>>>> On Thursday, 16 January 2020 17:37:31 UTC+2, Paavo Helde  wrote:
>>>>>> In C++ there is a preprocessor step which logically comes first and
>>>>>> prepares the preprocessed source consisting of remaining tokens.
>>>>>> However, preprocessor is line-based, so it ought to conflict with the
>>>>>> multi-line string literals:
>>>>>>
>>>>>> #include <iostream>
>>>>>>
>>>>>> #if 1
>>>>>>
>>>>>> int main() {
>>>>>> 	const char* test = R"__(
>>>>>>
>>>>>> #else
>>>>>>
>>>>>>         )__";
>>>>>> 	std::cout << test;
>>>>>> }
>>>>>>
>>>>>> #endif
>>>>>>
>>>>>> Obviously C++ compilers supporting C++11 are able to cope with that and
>>>>>> handle the '#else' line as part of the string literal. My question is
>>>>>> more about how they were able to standardize this behavior? Is there
>>>>>> still a logically separate preprocessor step or not?
>>>>>>
>>>>>> By googling I also find some EBNF formal syntax descriptions for C++,
>>>>>> but these are different for the preprocessor and for the actual C++
>>>>>> language. With presence of multi-line string literals, is it even
>>>>>> possible to provide a self-consistent EBNF formal syntax for the C++
>>>>>> preprocessor?
>>>>>
>>>>> [lex.phases]1.1.
>>>>> | Physical source file characters are mapped, in an implementation-defined
>>>>> | manner, to the basic source character set (introducing new-line
>>>>> | characters for end-of-line indicators) if necessary. The set of
>>>>> | physical source file characters accepted is implementation-defined. Any
>>>>> | source file character not in the basic source character set (5.3) is
>>>>> | replaced by the universal-character-name that designates that
>>>>> | character. An implementation may use any internal encoding, so long
>>>>> | as an actual extended character encountered in the source file, and
>>>>> | the same extended character expressed in the source file as a
>>>>> | universal-charactername (e.g., using the \uXXXX notation), are
>>>>> | handled equivalently except where this replacement is reverted (5.4)
>>>>> | in a *raw* *string* *literal*.
>>>>>
>>>>> So the raw string literal is already a token of very first translation
>>>>> step. Preprocessing takes place in step 4. By that time it has been
>>>>> string literal for 3 steps already.
>>>>>
>>>>
>>>> (Using n4820.pdf)
>>>> I think the reference in here of a string literal is a forward reference
>>>> (to section 5.4 [lex.pptoken]) and it only applies to handling of
>>>> universal-character-names, it does not define string literals yet.
>>>>
>>>> However, step 3 of [lex.phases] says: "The source file is decomposed
>>>> into preprocessing tokens (5.4)".
>>>> Preprocessing tokens are defined in [lex.pptoken] (section 5.4 in
>>>> n4820), and the list includes "string-literal" (specifically, it is
>>>> defined at p3.1).
>>>> The following step 4 then executes preprocessing directives.
>>>>
>>>> So, yes string literals are processed before preprocessing directives,
>>>> but one step earlier, not three.
>>>
>>> Are you suggesting what are the raw string literals should be
>>> re-decided in later steps?
>>>
>>>
>>
>> No, "what are the raw string literals" is "decided" in step 3, and not
>> in step 1.
>> I suggest you re-read step 1, more carefully.
> 
> Maybe I am confused indeed. Can we compose raw string literals
> using \u0052 <- 'R' in step 1 for later steps?
> 

Step 1 is not about composing raw string literals.
Do you mean \u0052"__(Hello World!)__" ?

This doesn't seem to work, in fact step 1 talks about conversion of 
"extended characters", and R is not an extended character.

[lex.charset] says that "The universal-character-name construct provides 
a way to name other characters" than the basic ones.

This might be the reason why gcc complains about universal character not 
allowed in the above.

[toc] | [prev] | [next] | [standalone]


#71424

Fromlegalize+jeeves@mail.xmission.com (Richard)
Date2020-01-16 20:07 +0000
Message-ID<qvqfp4$nit$1@news.xmission.com>
In reply to#71419
[Please do not mail me a copy of your followup]

Paavo Helde <myfirstname@osa.pri.ee> spake the secret code
<qvpvvf$h2p$1@dont-email.me> thusly:

>Obviously C++ compilers supporting C++11 are able to cope with that and 
>handle the '#else' line as part of the string literal. My question is 
>more about how they were able to standardize this behavior? Is there 
>still a logically separate preprocessor step or not?

In N3242, section "2.14.5 String literals" it gives the description for
a raw string literal.  String literals are one of the tokens seen by
the preprocessor as described in section "2.7 Tokens".

<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf>

So yes, raw string literals are turned into a single token as seen by
the preprocessor.
-- 
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
            The Terminals Wiki <http://terminals-wiki.org>
     The Computer Graphics Museum <http://computergraphicsmuseum.org>
  Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

[toc] | [prev] | [next] | [standalone]


#71468

FromJuha Nieminen <nospam@thanks.invalid>
Date2020-01-20 13:53 +0000
Message-ID<r04bcm$32j$2@adenine.netfront.net>
In reply to#71419
Paavo Helde <myfirstname@osa.pri.ee> wrote:
> In C++ there is a preprocessor step which logically comes first and 
> prepares the preprocessed source consisting of remaining tokens. 
> However, preprocessor is line-based, so it ought to conflict with the 
> multi-line string literals:
> 
> #include <iostream>
> 
> #if 1
> 
> int main() {
>        const char* test = R"__(
> 
> #else
> 
>     )__";
>        std::cout << test;
> }
> 
> #endif

How about the other way around? Is this valid C++ or not?

//------------------------------
#include <iostream>

#define TEST R"#(line1
line2
line3
)#"

int main()
{
    std::cout << TEST;
}
//------------------------------

[toc] | [prev] | [next] | [standalone]


#71469

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2020-01-20 18:31 +0200
Message-ID<r04kko$oe9$1@dont-email.me>
In reply to#71468
On 20.01.2020 15:53, Juha Nieminen wrote:
> Paavo Helde <myfirstname@osa.pri.ee> wrote:
>> In C++ there is a preprocessor step which logically comes first and
>> prepares the preprocessed source consisting of remaining tokens.
>> However, preprocessor is line-based, so it ought to conflict with the
>> multi-line string literals:
>>
>> #include <iostream>
>>
>> #if 1
>>
>> int main() {
>>         const char* test = R"__(
>>
>> #else
>>
>>      )__";
>>         std::cout << test;
>> }
>>
>> #endif
>
> How about the other way around? Is this valid C++ or not?
>
> //------------------------------
> #include <iostream>
>
> #define TEST R"#(line1
> line2
> line3
> )#"
>
> int main()
> {
>      std::cout << TEST;
> }
> //------------------------------
>

Apparently it is valid, and for the same reasons as my original example 
- the multi-line string literal is a single preprocessor token.

My original confusion came from the false impression that the 
preprocessor operates on line basis.

[toc] | [prev] | [next] | [standalone]


#71470

FromBonita Montero <Bonita.Montero@gmail.com>
Date2020-01-20 18:19 +0100
Message-ID<r04nfl$9c7$1@news.albasani.net>
In reply to#71468
> How about the other way around? Is this valid C++ or not?
> 
> //------------------------------
> #include <iostream>
> 
> #define TEST R"#(line1
> line2
> line3
> )#"
> 
> int main()
> {
>      std::cout << TEST;
> }
> //------------------------------

Doesn't matter if this is valid or not because no one does
such stupid things.

[toc] | [prev] | [next] | [standalone]


#71478

FromJuha Nieminen <nospam@thanks.invalid>
Date2020-01-21 08:24 +0000
Message-ID<r06cfk$27iu$1@adenine.netfront.net>
In reply to#71470
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>> How about the other way around? Is this valid C++ or not?
>> 
>> //------------------------------
>> #include <iostream>
>> 
>> #define TEST R"#(line1
>> line2
>> line3
>> )#"
>> 
>> int main()
>> {
>>      std::cout << TEST;
>> }
>> //------------------------------
> 
> Doesn't matter if this is valid or not because no one does
> such stupid things.

I am tempted to use less-than-pleasant words as a response, but I think
I will abstain. Instead, I will present an actual real-life situation where
such a thing is useful.

When programming with something that uses OpenGL, and thus GLSL for shaders,
the shaders are their own programming language inside strings. You could have
these GLSL sources in separate files, or you could have them as string literals
inside your program. The advantage of having them as string literals is that
you don't need to include extraneous files in your project (which may even be
easily modified by somebody), and you can build your strings from parts.

If there's some common GLSL code that could be useful in several shaders, you
can create string literales by concatenating separate ones. One easy way to do
that is to use macros for the string literals containing common code.

So you could have something like:

#define GLSL_COMMON_FUNC R"#(
float func(float) {
  ... whatever ...
}
)#"

After which you can create a shader using that function like

const char* const myShader = GLSL_COMMON_FUNC
"void main() { etc etc }"

Sure, you could just add the \ symbols at the end of each line in the macro,
but why bother, if you don't have to?

[toc] | [prev] | [next] | [standalone]


#71490

Fromboltar@nowhere.org
Date2020-01-21 16:43 +0000
Message-ID<r079n4$1i90$1@gioia.aioe.org>
In reply to#71478
On Tue, 21 Jan 2020 08:24:22 -0000 (UTC)
Juha Nieminen <nospam@thanks.invalid> wrote:
>Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> How about the other way around? Is this valid C++ or not?
>>> 
>>> //------------------------------
>>> #include <iostream>
>>> 
>>> #define TEST R"#(line1
>>> line2
>>> line3
>>> )#"
>>> 
>>> int main()
>>> {
>>>      std::cout << TEST;
>>> }
>>> //------------------------------
>> 
>> Doesn't matter if this is valid or not because no one does
>> such stupid things.
>
>I am tempted to use less-than-pleasant words as a response, but I think
>I will abstain. Instead, I will present an actual real-life situation where
>such a thing is useful.
>
>When programming with something that uses OpenGL, and thus GLSL for shaders,
>the shaders are their own programming language inside strings. You could have
>these GLSL sources in separate files, or you could have them as string literals
>
>inside your program. The advantage of having them as string literals is that
>you don't need to include extraneous files in your project (which may even be
>easily modified by somebody), and you can build your strings from parts.
>
>If there's some common GLSL code that could be useful in several shaders, you
>can create string literales by concatenating separate ones. One easy way to do
>that is to use macros for the string literals containing common code.
>
>So you could have something like:
>
>#define GLSL_COMMON_FUNC R"#(
>float func(float) {
>  ... whatever ...
>}
>)#"

Not with Clang you can't:

t.c:3:27: warning: missing terminating '"' character [-Winvalid-pp-token]
#define GLSL_COMMON_FUNC R"#(
                          ^
t.c:7:1: error: expected identifier or '('
)#"
^
t.c:7:3: warning: missing terminating '"' character [-Winvalid-pp-token]
)#"

Is this a gcc extension?

[toc] | [prev] | [next] | [standalone]


#71492

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2020-01-21 19:25 +0200
Message-ID<r07c5j$aag$1@dont-email.me>
In reply to#71490
On 21.01.2020 18:43, boltar@nowhere.org wrote:
> On Tue, 21 Jan 2020 08:24:22 -0000 (UTC)
> Juha Nieminen <nospam@thanks.invalid> wrote:
>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> How about the other way around? Is this valid C++ or not?
>>>>
>>>> //------------------------------
>>>> #include <iostream>
>>>>
>>>> #define TEST R"#(line1
>>>> line2
>>>> line3
>>>> )#"
>>>>
>>>> int main()
>>>> {
>>>>       std::cout << TEST;
>>>> }
>>>> //------------------------------
>>>
>>> Doesn't matter if this is valid or not because no one does
>>> such stupid things.
>>
>> I am tempted to use less-than-pleasant words as a response, but I think
>> I will abstain. Instead, I will present an actual real-life situation where
>> such a thing is useful.
>>
>> When programming with something that uses OpenGL, and thus GLSL for shaders,
>> the shaders are their own programming language inside strings. You could have
>> these GLSL sources in separate files, or you could have them as string literals
>>
>> inside your program. The advantage of having them as string literals is that
>> you don't need to include extraneous files in your project (which may even be
>> easily modified by somebody), and you can build your strings from parts.
>>
>> If there's some common GLSL code that could be useful in several shaders, you
>> can create string literales by concatenating separate ones. One easy way to do
>> that is to use macros for the string literals containing common code.
>>
>> So you could have something like:
>>
>> #define GLSL_COMMON_FUNC R"#(
>> float func(float) {
>>   ... whatever ...
>> }
>> )#"
>
> Not with Clang you can't:
>
> t.c:3:27: warning: missing terminating '"' character [-Winvalid-pp-token]
> #define GLSL_COMMON_FUNC R"#(
>                            ^
> t.c:7:1: error: expected identifier or '('
> )#"
> ^
> t.c:7:3: warning: missing terminating '"' character [-Winvalid-pp-token]
> )#"
>
> Is this a gcc extension?
>

https://godbolt.org/ shows that this compiles fine with clang 6.0.0 and 
later. Clang 5.0.0 indeed fails - it looks like it's time to upgrade, 
the current version is 9.0.0.

[toc] | [prev] | [next] | [standalone]


#71501

Fromboltar@nowhere.org
Date2020-01-22 09:58 +0000
Message-ID<r096c0$hpr$1@gioia.aioe.org>
In reply to#71492
On Tue, 21 Jan 2020 19:25:06 +0200
Paavo Helde <myfirstname@osa.pri.ee> wrote:
>On 21.01.2020 18:43, boltar@nowhere.org wrote:
>> Not with Clang you can't:
>>
>> t.c:3:27: warning: missing terminating '"' character [-Winvalid-pp-token]
>> #define GLSL_COMMON_FUNC R"#(
>>                            ^
>> t.c:7:1: error: expected identifier or '('
>> )#"
>> ^
>> t.c:7:3: warning: missing terminating '"' character [-Winvalid-pp-token]
>> )#"
>>
>> Is this a gcc extension?
>>
>
>https://godbolt.org/ shows that this compiles fine with clang 6.0.0 and 
>later. Clang 5.0.0 indeed fails - it looks like it's time to upgrade, 
>the current version is 9.0.0.

They can say it compiles fine all they like, I'm telling you it doesn't:

fenris$ clang -v
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
fenris$ cat t.c
#define GLSL_COMMON_FUNC R"#(
float func(float f) {
	return 0.0;
>}
>)#"

int main()
{
	return 0;
}
fenris$ cc t.c
t.c:1:27: warning: missing terminating '"' character [-Winvalid-pp-token]
#define GLSL_COMMON_FUNC R"#(
                          ^
t.c:4:1: error: expected expression
>}
^
t.c:4:2: error: expected expression
>}
 ^
t.c:5:1: error: expected identifier or '('
>)#"
^
t.c:5:4: warning: missing terminating '"' character [-Winvalid-pp-token]
>)#"
   ^
2 warnings and 3 errors generated.
fenris$ mv t.c t.cc
fenris$ c++ t.cc
t.cc:1:27: warning: missing terminating '"' character [-Winvalid-pp-token]
#define GLSL_COMMON_FUNC R"#(
                          ^
t.cc:4:1: error: expected expression
>}
^
t.cc:4:2: error: expected expression
>}
 ^
t.cc:5:1: error: expected unqualified-id
>)#"
^
t.cc:5:4: warning: missing terminating '"' character [-Winvalid-pp-token]
>)#"
   ^
2 warnings and 3 errors generated.

[toc] | [prev] | [next] | [standalone]


#71503

Fromguinness.tony@gmail.com
Date2020-01-22 02:11 -0800
Message-ID<789965ca-739a-48cd-940a-8cdb66f4fd40@googlegroups.com>
In reply to#71501
On Wednesday, 22 January 2020 09:58:35 UTC, bol...@nowhere.org  wrote:
> On Tue, 21 Jan 2020 19:25:06 +0200
> Paavo Helde <myfirstname@osa.pri.ee> wrote:
> >On 21.01.2020 18:43, boltar@nowhere.org wrote:
> >> Not with Clang you can't:
> >>
> >> t.c:3:27: warning: missing terminating '"' character [-Winvalid-pp-token]
> >> #define GLSL_COMMON_FUNC R"#(
> >>                            ^
> >> t.c:7:1: error: expected identifier or '('
> >> )#"
> >> ^
> >> t.c:7:3: warning: missing terminating '"' character [-Winvalid-pp-token]
> >> )#"
> >>
> >> Is this a gcc extension?
> >>
> >
> >https://godbolt.org/ shows that this compiles fine with clang 6.0.0 and 
> >later. Clang 5.0.0 indeed fails - it looks like it's time to upgrade, 
> >the current version is 9.0.0.
> 
> They can say it compiles fine all they like, I'm telling you it doesn't:
> 
> fenris$ clang -v
> Apple LLVM version 10.0.1 (clang-1001.0.46.4)
> Target: x86_64-apple-darwin18.7.0
> Thread model: posix
> InstalledDir: /Library/Developer/CommandLineTools/usr/bin
> fenris$ cat t.c
> #define GLSL_COMMON_FUNC R"#(
> float func(float f) {
> 	return 0.0;
> >}
> >)#"
> 
> int main()
> {
> 	return 0;
> }
> fenris$ cc t.c
> t.c:1:27: warning: missing terminating '"' character [-Winvalid-pp-token]
> #define GLSL_COMMON_FUNC R"#(
>                           ^
> t.c:4:1: error: expected expression
> >}
> ^
> t.c:4:2: error: expected expression
> >}
>  ^
> t.c:5:1: error: expected identifier or '('
> >)#"
> ^
> t.c:5:4: warning: missing terminating '"' character [-Winvalid-pp-token]
> >)#"
>    ^
> 2 warnings and 3 errors generated.
> fenris$ mv t.c t.cc
> fenris$ c++ t.cc
> t.cc:1:27: warning: missing terminating '"' character [-Winvalid-pp-token]
> #define GLSL_COMMON_FUNC R"#(
>                           ^
> t.cc:4:1: error: expected expression
> >}
> ^
> t.cc:4:2: error: expected expression
> >}
>  ^
> t.cc:5:1: error: expected unqualified-id
> >)#"
> ^
> t.cc:5:4: warning: missing terminating '"' character [-Winvalid-pp-token]
> >)#"
>    ^
> 2 warnings and 3 errors generated.

It does if you use the C++ compiler (you're using the C compiler, above).

C doesn't have raw string literals; C++ does.

[toc] | [prev] | [next] | [standalone]


#71504

Fromboltar@nowhere.org
Date2020-01-22 10:24 +0000
Message-ID<r097to$pfj$1@gioia.aioe.org>
In reply to#71503
On Wed, 22 Jan 2020 02:11:24 -0800 (PST)
guinness.tony@gmail.com wrote:
>On Wednesday, 22 January 2020 09:58:35 UTC, bol...@nowhere.org  wrote:
>> On Tue, 21 Jan 2020 19:25:06 +0200
>> Paavo Helde <myfirstname@osa.pri.ee> wrote:
>> >On 21.01.2020 18:43, boltar@nowhere.org wrote:
>> >> Not with Clang you can't:
>> >>
>> >> t.c:3:27: warning: missing terminating '"' character [-Winvalid-pp-token]
>> >> #define GLSL_COMMON_FUNC R"#(
>> >>                            ^
>> >> t.c:7:1: error: expected identifier or '('
>> >> )#"
>> >> ^
>> >> t.c:7:3: warning: missing terminating '"' character [-Winvalid-pp-token]
>> >> )#"
>> >>
>> >> Is this a gcc extension?
>> >>
>> >
>> >https://godbolt.org/ shows that this compiles fine with clang 6.0.0 and 
>> >later. Clang 5.0.0 indeed fails - it looks like it's time to upgrade, 
>> >the current version is 9.0.0.
>> 
>> They can say it compiles fine all they like, I'm telling you it doesn't:
>> 
>> fenris$ clang -v
>> Apple LLVM version 10.0.1 (clang-1001.0.46.4)
>> Target: x86_64-apple-darwin18.7.0
>> Thread model: posix
>> InstalledDir: /Library/Developer/CommandLineTools/usr/bin
>> fenris$ cat t.c
>> #define GLSL_COMMON_FUNC R"#(
>> float func(float f) {
>> 	return 0.0;
>> >}
>> >)#"
>> 
>> int main()
>> {
>> 	return 0;
>> }
>> fenris$ cc t.c
>> t.c:1:27: warning: missing terminating '"' character [-Winvalid-pp-token]
>> #define GLSL_COMMON_FUNC R"#(
>>                           ^
>> t.c:4:1: error: expected expression
>> >}
>> ^
>> t.c:4:2: error: expected expression
>> >}
>>  ^
>> t.c:5:1: error: expected identifier or '('
>> >)#"
>> ^
>> t.c:5:4: warning: missing terminating '"' character [-Winvalid-pp-token]
>> >)#"
>>    ^
>> 2 warnings and 3 errors generated.
>> fenris$ mv t.c t.cc
>> fenris$ c++ t.cc
>> t.cc:1:27: warning: missing terminating '"' character [-Winvalid-pp-token]
>> #define GLSL_COMMON_FUNC R"#(
>>                           ^
>> t.cc:4:1: error: expected expression
>> >}
>> ^
>> t.cc:4:2: error: expected expression
>> >}
>>  ^
>> t.cc:5:1: error: expected unqualified-id
>> >)#"
>> ^
>> t.cc:5:4: warning: missing terminating '"' character [-Winvalid-pp-token]
>> >)#"
>>    ^
>> 2 warnings and 3 errors generated.
>
>It does if you use the C++ compiler (you're using the C compiler, above).

Are you blind? Try looking a bit harder.

[toc] | [prev] | [next] | [standalone]


#71535

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-23 22:25 -0500
Message-ID<r0do3o$djl$1@dont-email.me>
In reply to#71503
On 1/22/20 5:11 AM, guinness.tony@gmail.com wrote:
> On Wednesday, 22 January 2020 09:58:35 UTC, bol...@nowhere.org  wrote:
...
>> fenris$ c++ t.cc
>> t.cc:1:27: warning: missing terminating '"' character [-Winvalid-pp-token]
>> #define GLSL_COMMON_FUNC R"#(
>>                           ^
>> t.cc:4:1: error: expected expression
>>> }
>> ^
>> t.cc:4:2: error: expected expression
>>> }
>>  ^
>> t.cc:5:1: error: expected unqualified-id
>>> )#"
>> ^
>> t.cc:5:4: warning: missing terminating '"' character [-Winvalid-pp-token]
>>> )#"
>>    ^
>> 2 warnings and 3 errors generated.
> 
> It does if you use the C++ compiler (you're using the C compiler, above).
> 
> C doesn't have raw string literals; C++ does.

How did you conclude that c++ is the name of a C compiler?

[toc] | [prev] | [next] | [standalone]


#71508

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2020-01-22 13:28 +0200
Message-ID<r09bk9$50e$1@dont-email.me>
In reply to#71501
On 22.01.2020 11:58, boltar@nowhere.org wrote:
> On Tue, 21 Jan 2020 19:25:06 +0200
> Paavo Helde <myfirstname@osa.pri.ee> wrote:
>> On 21.01.2020 18:43, boltar@nowhere.org wrote:
>>> Not with Clang you can't:
>>>
>>> t.c:3:27: warning: missing terminating '"' character [-Winvalid-pp-token]
>>> #define GLSL_COMMON_FUNC R"#(
>>>                             ^
>>> t.c:7:1: error: expected identifier or '('
>>> )#"
>>> ^
>>> t.c:7:3: warning: missing terminating '"' character [-Winvalid-pp-token]
>>> )#"
>>>
>>> Is this a gcc extension?
>>>
>>
>> https://godbolt.org/ shows that this compiles fine with clang 6.0.0 and
>> later. Clang 5.0.0 indeed fails - it looks like it's time to upgrade,
>> the current version is 9.0.0.
>
> They can say it compiles fine all they like, I'm telling you it doesn't:
>
> fenris$ clang -v
> Apple LLVM version 10.0.1 (clang-1001.0.46.4)
> Target: x86_64-apple-darwin18.7.0
> Thread model: posix
> InstalledDir: /Library/Developer/CommandLineTools/usr/bin
[...]
> fenris$ c++ t.cc

And how is this 'c++' program related to the 'clang' program you used 
for -v?

> t.cc:1:27: warning: missing terminating '"' character [-Winvalid-pp-token]
> #define GLSL_COMMON_FUNC R"#(
>                            ^
> t.cc:4:1: error: expected expression
>> }
> ^
> t.cc:4:2: error: expected expression
>> }
>   ^
> t.cc:5:1: error: expected unqualified-id
>> )#"
> ^
> t.cc:5:4: warning: missing terminating '"' character [-Winvalid-pp-token]
>> )#"
>     ^
> 2 warnings and 3 errors generated.

Your example works fine with my clang:

gemma$ clang++ -v
clang version 7.0.1 (tags/RELEASE_701/final 349238)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-suse-linux/7
Found candidate GCC installation: /usr/lib64/gcc/x86_64-suse-linux/7
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-suse-linux/7
Candidate multilib: .;@m64
Selected multilib: .;@m64
gemma$ cat test1.cpp
#include <iostream>

#define GLSL_COMMON_FUNC R"#(
float func(float f) {
         return 0.0;
}
)#"

int main()
{
         std::cout << GLSL_COMMON_FUNC;
}
gemma$ clang++ test1.cpp
gemma$ ./a.out

float func(float f) {
         return 0.0;
}

[toc] | [prev] | [next] | [standalone]


#71510

Fromboltar@nowhere.org
Date2020-01-22 12:07 +0000
Message-ID<r09dt8$1oh5$1@gioia.aioe.org>
In reply to#71508
On Wed, 22 Jan 2020 13:28:08 +0200
Paavo Helde <myfirstname@osa.pri.ee> wrote:
>On 22.01.2020 11:58, boltar@nowhere.org wrote:
>> On Tue, 21 Jan 2020 19:25:06 +0200
>> fenris$ clang -v
>> Apple LLVM version 10.0.1 (clang-1001.0.46.4)
>> Target: x86_64-apple-darwin18.7.0
>> Thread model: posix
>> InstalledDir: /Library/Developer/CommandLineTools/usr/bin
>[...]
>> fenris$ c++ t.cc
>
>And how is this 'c++' program related to the 'clang' program you used 
>for -v?

fenris$ ls -l /usr/bin/c++
lrwxr-xr-x  1 root  wheel  7 27 Sep  2018 /usr/bin/c++ -> clang++

>gemma$ cat test1.cpp
>#include <iostream>
>
>#define GLSL_COMMON_FUNC R"#(
>float func(float f) {
>         return 0.0;
>}
>)#"
>
>int main()
>{
>         std::cout << GLSL_COMMON_FUNC;
>}
>gemma$ clang++ test1.cpp
>gemma$ ./a.out
>
>float func(float f) {
>         return 0.0;
>}

fenris$ c++ test1.cpp
test1.cpp:3:27: warning: missing terminating '"' character [-Winvalid-pp-token]
#define GLSL_COMMON_FUNC R"#(
                          ^
test1.cpp:7:1: error: expected unqualified-id
)#"
^
test1.cpp:7:3: warning: missing terminating '"' character [-Winvalid-pp-token]
)#"
  ^
2 warnings and 1 error generated.
fenris$ 

Perhaps Apples version of Clang is different in some way, but regardless, it
doesn't compile.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c++


csiph-web