3

The following code is supposed to output 6, but instead it outputs 5. I can't figure out why. What's going on?

#include <iostream>

template <typename T>
void foo(T& y)
{
   y++;
}

int main()
{
   int x = 5;

   // Why won't this line work???/
   foo(x);

   std::cout << x;
}

Live demo

johnchen902
  • 9,531
  • 1
  • 27
  • 69
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055

6 Answers6

21

Trigraphs

You're using the good ol' trick of trigraphs.

// Why won't this line work???/
                            | |
                            \ /
                             |
                         ~trigraph~

The ??/ trigraph is in turn converted to \ which basically concatenates the current line with the next line and thus your code becomes more or less like this:

// Why won't this line work? foo(x);

A fine trick indeed.


Quoting from the C++11 standard:

§2.2.2:

Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. ...

§2.4.1:

Table 1 - Trigraph sequences
...
==========================
| Trigraph | Replacement |
==========================
|          ...           |
==========================
|   ??/    |      \      |
==========================

Fortunately, GCC seems to detect this kind of trickery, emitting a warning (just set -Wall):

main.cpp:13:32: warning: trigraph ??/ converted to \ [-Wtrigraphs]
    // Why won't this line work???/
 ^

main.cpp:13:4: warning: multi-line comment [-Wcomment]
    // Why won't this line work???/
    ^

Related references:

meaning of `???-` in C++ code

What is this smiley-with-beard expression: "<:]{%>"?

What does the C ??!??! operator do?

And all other similar questions out there. ??)

PS: That's a smiley.

Community
  • 1
  • 1
Mark Garcia
  • 17,424
  • 4
  • 58
  • 94
  • 2
    Oh! What an interesting and neat feature. – Lightness Races in Orbit Jul 03 '13 at 08:19
  • @LightnessRacesinOrbit Interesting? Yes! Neat? No! Useful? Absolutely Not! When do they finally drop rubbish like that from the standard (together with the literal versions of the logical operators). Show me a single person that needs those nowadays for more than just "party knowledge" (or maybe entries to a hypothetical *IOC++CC*). – Christian Rau Jul 03 '13 at 09:39
  • 1
    @ChristianRau that's some party... – Sam Holder Jul 03 '13 at 16:12
  • @LightnessRacesinOrbit you make out like you didn't know very convincingly. I'd like to see the programmer that writes a comment `// Why won't this line work???/` before a line that they haven't tested yet. That must be a very pessimistic person... – Sam Holder Jul 03 '13 at 16:14
8

??/ is a Trigraph sequence which is replaced with \.
For the compiler \ means that immediate line that follows is a part of the current line. In this case the current line is a comment. The effective result is:

// Why won't this line work foo(x);
Alok Save
  • 202,538
  • 53
  • 430
  • 533
4

It's Trigraphs. In c++11 specification

2.4 Trigraph sequences [lex.trigraph]

1 Before any other processing takes place, each occurrence of one of the following sequences of three characters (“trigraph sequences”) is replaced by the single character indicated in Table 1.

                     Table 1 — Trigraph sequences
    Trigraph Replacement │ Trigraph Replacement │ Trigraph Replacement
    ─────────────────────┼──────────────────────┼─────────────────────
       ??=      #        │    ??(      [        │    ??<      {
       ??/      \        │    ??)      ]        │    ??>      }
       ??’      ˆ        │    ??!      |        │    ??-      ~

Now replace ??/ with \ and you'll find out.

johnchen902
  • 9,531
  • 1
  • 27
  • 69
2
// Why won't this line work???/
   foo(x);

The trigraph ??/turns to \, so the code will be translated to:

// Why won't this line work?\
   foo(x);

And string concatenation works.

When I tested it in g++, trigraph is turned off by default(generates a warning), it will output 6. If compiled using g++ t.cpp -trigraphs, will output 5.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
2

probably your comment is interpreted as a trigraph (not treegraph!) that "deletes" the function call.

http://ideone.com/sU4YGc works for me deleting that ??/ in the comment.

// Why won't this line work?
foo(x);

see also Purpose of Trigraph sequences in C++?

Community
  • 1
  • 1
DRC
  • 4,898
  • 2
  • 21
  • 35
1

The compiler is your friend. This

   // Why won't this line work???/
   foo(x);

is a multiline comment, foo(x) is not executed!

The trigraph "??/" is converted to "\" which indicates a linebreak into the comment.

Stefano Falasca
  • 8,837
  • 2
  • 18
  • 24