Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #71419 > unrolled thread
| Started by | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| First post | 2020-01-16 17:37 +0200 |
| Last post | 2020-01-22 12:03 +0000 |
| Articles | 20 on this page of 26 — 10 participants |
Back to article view | Back to comp.lang.c++
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 →
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2020-01-16 17:37 +0200 |
| Subject | C++ 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]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2020-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]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2020-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]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2020-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]
| From | Manfred <invalid@add.invalid> |
|---|---|
| Date | 2020-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]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2020-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]
| From | Manfred <invalid@add.invalid> |
|---|---|
| Date | 2020-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]
| From | legalize+jeeves@mail.xmission.com (Richard) |
|---|---|
| Date | 2020-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2020-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2020-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2020-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]
| From | boltar@nowhere.org |
|---|---|
| Date | 2020-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2020-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]
| From | boltar@nowhere.org |
|---|---|
| Date | 2020-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]
| From | guinness.tony@gmail.com |
|---|---|
| Date | 2020-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]
| From | boltar@nowhere.org |
|---|---|
| Date | 2020-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2020-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]
| From | boltar@nowhere.org |
|---|---|
| Date | 2020-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