Quote-Dot-Quote Operator

K

kvnsmnsn

I'm taking a look at some existing C++ code and trying to figure out
what it's doing. It says:

static char const *abc[] = {
"DEF", DEF,
"GHI", PQR_PQR_STRING "."
PQR_PQR_FUNC(PQR_VAR1, PQR_VAR2),
"JKL", JKL,
"MNO", "M_N_O",
0
};

where <DEF> and <JKL> are defined in <#include>ed header files in the
local directory, and I assume all the <PQR_*> entities are included in
header files somewhere. (I've changed all the variable names from
what the existing code says so that I can post this here.)

Now, apparently this is saying that the type of expression
<PQR_PQR_STRING "." PQR_PQR_FUNC(PQR_VAR1, PQR_VAR2)> is <char *>, be-
cause it's included as an element of the <abc> array. But is
<PQR_PQR_STRING "." PQR_PQR_FUNC(PQR_VAR1, PQR_VAR2)> even _valid syn-
tax_? It seems to be implying that quote-dot-quote is a valid opera-
tor, and if it is, that's news to me.

If someone can tell me why this compiles and what it means, I'd be
really, really grateful.

---Kevin Simonson

"You'll never get to heaven, or even to LA,
if you don't believe there's a way."
from _Why Not_
 
I

Ian Collins

I'm taking a look at some existing C++ code and trying to figure out
what it's doing. It says:

static char const *abc[] = {
"DEF", DEF,
"GHI", PQR_PQR_STRING "."
PQR_PQR_FUNC(PQR_VAR1, PQR_VAR2),
"JKL", JKL,
"MNO", "M_N_O",
0
};

where <DEF> and <JKL> are defined in <#include>ed header files in the
local directory, and I assume all the <PQR_*> entities are included in
header files somewhere. (I've changed all the variable names from
what the existing code says so that I can post this here.)

Now, apparently this is saying that the type of expression
<PQR_PQR_STRING "." PQR_PQR_FUNC(PQR_VAR1, PQR_VAR2)> is <char *>, be-
cause it's included as an element of the <abc> array. But is
<PQR_PQR_STRING "." PQR_PQR_FUNC(PQR_VAR1, PQR_VAR2)> even _valid syn-
tax_? It seems to be implying that quote-dot-quote is a valid opera-
tor, and if it is, that's news to me.
Hard to say without seeing the macros. They probably produce quoted
strings. The pre-processor will concatenate string literals into one
token, so

"1" "." "2" will be concatenated to "1.2".
 
S

Stefan Ram

Ian Collins said:
Hard to say without seeing the macros. They probably produce quoted
strings. The pre-processor will concatenate string literals into one
token, so

Preprocessing directives are executed and macro invocations
are expanded in translation phase 4, while adjacent ordinary
string literal tokens are concatenated in translation phase 6
(ISO/IEC ISO/IEC 14882:2003(E), 2.1).
 
F

Frank Birbacher

Hi!

Stefan said:
Preprocessing directives are executed and macro invocations
are expanded in translation phase 4, while adjacent ordinary
string literal tokens are concatenated in translation phase 6
(ISO/IEC ISO/IEC 14882:2003(E), 2.1).

Should that me the compiler concatenates them instead of the preprocessor?

Frank
 
J

James Kanze

Not necessarily, the standard does not define who does what.

More exactly, it defines it differently in different places.
Section 16 is "Preprocessing directives", treats the
preprocessor, and there's certainly no concatentation of string
literals there. On the other hand, "Each preprocessing token is
converted into a token" in phase 7, which certainly sounds to me
like everything earlier (including the concatenation of string
literals in phase 6) is preprocessor.

I don't think it really matters. The important thing is that it
happens. Before "The resulting tokens are syntactically and
semantically analyzed and translated as a translation unit."
(Which is interesting in itself. Why didn't they just define a
production for concatenating string literals?)
 
S

Stefan Ram

James Kanze said:
(Which is interesting in itself. Why didn't they just define a
production for concatenating string literals?)

Possibly, this way, the C++ grammar can be written more simple.

Also, it makes clear, that the concatenation »"a" "b"« never
is a run-time operation.

In C++ expressions usually the »substitutivity of identity«
holds, i.e., »any subexpression can be replaced by any other
equal in value« as long as there are no run-time effects, so

{ return 2 + 3; }

is the same as

{ int const a( 2 ); return a + 3; }

But, one does not want

{ return "a" "b"; }

to be the same as

{ char const * const a( "a" ); return a "b"; }

So, possibly the concatenation of string /literals/ but not
string-valued /expressions/ does not fit into the general
»substitutivity of identity« rule for C++ operators.

»The phases of translation are spelled out to resolve
questions raised about the precedence of different parses.
Can a #define begin a comment? (No.) Is backslash/new-line
permitted within a trigraph? (No.) Must a comment be
contained within one #include file? (Yes.) And so on. 25
The Rationale on preprocessing (§6.10) discusses the
reasons for many of the decisions that shaped the
specification of the phases of translation.«

Rationale for International Standard - Programming Languages - C
Revision 2, 20 October 1999

The idea of a grammar rule for »"a" "b"« as a concatenation
operation reminds me of

http://www.research.att.com/~bs/whitespace98.pdf
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top