omar
omar

Reputation: 629

Trigraphs in a comment, converted in c++11, ignored in c++17

Consider the following piece of code (notice the comment):

#include <iostream>

int main()
{
    int x = 1; // <-- Why??/
    x += 1;
    std::cout << x << std::endl;
}

To compile this program, I am using the GNU C++ Compiler g++:

$ g++ --version // g++ (Ubuntu 6.5.0-1ubuntu1~16.04) 6.5.0 20181026

Now, when compiling this for C++11 and C++17, I get different results (and warnings).

For C++11, g++ -std=c++11 trigraph.cpp -Wall:

trigraph.cpp:5:26: warning: trigraph ??/ converted to \ [-Wtrigraphs]
         int x = 1; // <-- Why??/

trigraph.cpp:5:16: warning: multi-line comment [-Wcomment]
         int x = 1; // <-- Why??/
                    ^
$ ./a.out
1

For C++17, g++ -std=c++17 trigraph.cpp -Wall:

trigraph.cpp:5:26: warning: trigraph ??/ ignored, use -trigraphs to enable [-Wtrigraphs]
     int x = 1; // <-- Why??/

$ ./a.out
2

After reading a bit about trigraphs, I understand that they were removed in C++17, thus ignored by the compiler as shown in the example above. However, in the case of C++11, even when it's in a comment it was converted!

Now, I can see how that would affect the code if the trigraph was in a character string for instance. But, in this example, shouldn't it be ignored since it's in a comment?

After removing the trailing forward slash ("/") from the comment, all warnings disappeared. My question is what did exactly happen here? Why the output is different?

Upvotes: 11

Views: 1792

Answers (3)

Yksisarvinen
Yksisarvinen

Reputation: 22176

Trigraphs are are very old way to insert certain characters into code, which were possibly not available on all keybords. For full list, see cppreference.

In your example, you accidentally created one of the trigraphs ??/, which is translated into \. Trailing \ has a special meaning - it tells the compiler to ignore line break and treat next line as part of the current line.

Your code would be translated like this:

int x = 1; // <-- Why??/
x += 1; 

int x = 1; // <-- Why\
x += 1;

int x = 1; // <-- Why x += 1;

This is what the warnings actually mean. Trigraph was interpreted and changed into \, and it created a multi line comment, even though you used //.

Now, trigraphs became depracated in C++11 and were removed from standard in C++17. This means, when compiling in C++11 your trigraph was translated, but in C++17 it was ignored (and compiler sent you a note that you can still enable them).

Upvotes: 8

perivesta
perivesta

Reputation: 4021

The trigraph ??/ gets converted by the compiler to \ before actual compilation happens (i.e. before comments are removed).

So these lines

int x = 1; // <-- Why??/
x += 1;

get converted to

int x = 1; // <-- Why\
x += 1;

A backslash at the end of a line appends the next line to it. So it becomes

int x = 1; // <-- Why    x += 1;

Which moves the statement x+=1; into the comment and thus it is not compiled.

When you remove the trailing /, it is not a trigraph anymore (sincce it's now only ??) and nothing special happens.

Upvotes: 6

Jaffa
Jaffa

Reputation: 12700

If ??/ is converted to \ then ??// would be converted to \/.

Or // also starts a comment, so the application rule for trigraphs comes first, and only after that does the compiler check whether it's a comment or not.

Upvotes: 3

Related Questions