Topic: user-defined literals and macros


Author: cryptooctoploid@gmail.com
Date: Sun, 30 Oct 2011 11:09:30 -0700 (PDT)
Raw View
Consider:
  % cat liter.cpp
#define BAR "foo"
int main()
{
   char *foobar("foo/"BAR);
}

  % g++ liter.cpp -std=gnu++0x
liter.cpp: In function    int main()   :
liter.cpp:4:16: error: unable to find user-defined string literal operator    operator"" BAR

Is this the expected behavior?


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Johannes Schaub <schaub.johannes@googlemail.com>
Date: Mon, 31 Oct 2011 11:10:22 -0700 (PDT)
Raw View
cryptooctoploid@gmail.com wrote:

> Consider:
>   % cat liter.cpp
> #define BAR "foo"
> int main()
> {
>    char *foobar("foo/"BAR);
> }
>
>   % g++ liter.cpp -std=gnu++0x
> liter.cpp: In function    int main()   :
> liter.cpp:4:16: error: unable to find user-defined string literal operator
>    operator"" BAR
>
> Is this the expected behavior?
>
>

Yes. The token "foo/"BAR  is one single preprocessor token (/user-defined-
string-literal/). So it does not denote an identifier token BAR and so shall
not be replaced by the macro. You need to put whitespace between "foo/" and
BAR in order to make BAR an /identifier/ preprocessing token of its own.

It shall be noted that while BAR *is* an /identifier/ non-terminal in the
grammar used to specify /user-defined-string-literal/, it is not a
preprocessing-token of that name, so the preprocessor will not see it as an
identifier.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Ed Smith-Rowland <3dw4rd@verizon.net>
Date: Mon, 31 Oct 2011 11:11:39 -0700 (PDT)
Raw View
On Oct 30, 2:09 pm, cryptooctopl...@gmail.com wrote:
> Consider:
>   % cat liter.cpp
> #define BAR "foo"
> int main()
> {
>    char *foobar("foo/"BAR);
>
> }
>
>   % g++ liter.cpp -std=gnu++0x
> liter.cpp: In function    int main()   :
> liter.cpp:4:16: error: unable to find user-defined string literal operator    operator"" BAR
>
> Is this the expected behavior?
>
> --
> [ comp.std.c++ is moderated.  To submit articles, try posting with your ]
> [ newsreader.  If that fails, use mailto:std-cpp-sub...@vandevoorde.com ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]

Yes, this is now the expected behavior.  "foo/"BAR is now considered a
single lexical token - a user-defined string literal.  The compiler
will look for 'operator"" BAR(const char*, std::size_t)' and if found
insert a call at the location of the literal 'operator"" BAR("foo/",
5)'.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: David Krauss <potswa@gmail.com>
Date: Mon, 31 Oct 2011 11:11:11 -0700 (PDT)
Raw View
On Oct 30, 10:09 am, cryptooctopl...@gmail.com wrote:
> Consider:
>   % cat liter.cpp
> #define BAR "foo"
> int main()
> {
>    char *foobar("foo/"BAR);
>
> }
>
>   % g++ liter.cpp -std=gnu++0x
> liter.cpp: In function    int main()   :
> liter.cpp:4:16: error: unable to find user-defined string literal operator    operator"" BAR
>
> Is this the expected behavior?

Yes. An identifier following the literal is a ud-suffix, not a
separate token eligible for macro expansion. The grammar production
rules are

preprocessing-token : user-defined-string-literal
user-defined-string-literal : string-literal identifier

See subclauses 2.5 and 2.14. There is also a similar example in the
compatibility appendix.

Simply insert a space to fix the problem.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: =?windows-1252?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Mon, 31 Oct 2011 11:12:33 -0700 (PDT)
Raw View
Am 30.10.2011 19:09, schrieb cryptooctoploid@gmail.com:
> Consider:
>    % cat liter.cpp
> #define BAR "foo"
> int main()
> {
>     char *foobar("foo/"BAR);
> }
>
>    % g++ liter.cpp -std=gnu++0x
> liter.cpp: In function    int main()   :
> liter.cpp:4:16: error: unable to find user-defined string literal operator    operator"" BAR
>
> Is this the expected behavior?

Yes, this is a known backward-compatibility break of C++11, it is listed
in annex C.2.1, 2.5:

<quote>
Change: User-defined literal string support
Rationale: Required for new features.
Effect on original feature: Valid C++ 2003 code may fail to compile or
produce different results in this International Standard, as the
following example illustrates.

#define _x "there"
"hello"_x // #1

Previously, #1 would have consisted of two separate preprocessing tokens
and the macro _x would have been expanded. In this International
Standard, #1 consists of a single preprocessing tokens, so the macro
is not expanded.
</quote>

HTH & Greetings from Bremen,

Daniel Kr   gler


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Ed Smith-Rowland<3dw4rd@verizon.net>
Date: Tue, 1 Nov 2011 11:14:56 -0700 (PDT)
Raw View
I made an error.  The call is 'operator"" BAR("foo/", 4)'.  The length of the string is *without* the terminating null.  Sorry.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]