Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c++11

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?

like image 719
omar Avatar asked Nov 15 '18 09:11

omar


1 Answers

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).

like image 182
Yksisarvinen Avatar answered Sep 18 '22 15:09

Yksisarvinen