You have "accidentally" written a trigraph somewhere in your source code (the compiler's warning would pinpoint the line). Since trigraphs were invented to solve a problem that doesn't come into play on modern systems, you don't actually want the trigraph ??/
to be replaced with the character \
.
Therefore, this warning should probably be ignored (you can tell the compiler to shut up by adding -Wno-trigraphs
after -Wall
in your command line; see the docs). But it would be good to show your source code so we can be sure.
Trigraphs are more problematic to the unaware user than digraphs. This is because they are replaced within string literals and comments. Here are some examples…
Example A:
std::string example = "What??!??!";
std::cout << example << std::endl;
What||
will be printed to the console. This is because of the trigraph ??!
being translated to |
.
Example B:
// Error ?!?!?!??!??/
std::cout << "There was an error!" << std::endl;
Nothing will happen at all. This is because ??/
translates to \
, which escapes the newline character and results in the next line being commented out.
Example C:
// This makes no sense ?!?!!?!??!??/
std::string example = "Hello World";
std::cout << example << std::endl;
This will give an error along the lines of use of undeclared identifier "example"
for the same reasons as Example B.
There are far more elaborate problems trigraphs can cause too, but you get the idea. It's worth noting that many compilers actually emit a warning when such translations are being made; yet another reason to always treat warnings as errors. However this is not required by the standard and therefore cannot be relied upon.
Digraphs are much less problematic than trigraphs, as they are not replaced inside another token (i.e. a string or character literal) and there is not a sequence that translates to \
, so escaping new lines in comments cannot occur.
Conclusion
Other than harder to read code, there are less problems caused by digraphs and therefore the need to remove them is greatly reduced.
Best Answer
Trigraphs were introduced by the 1989 ANSI C standard, and are retained in all later C standards (so far; the upcoming C23 standard will drop them). They also appear in the first ISO C++ standard, published in 1998, and in all later C++ standards up to and including C++14. (Trigraphs were removed in C++17. Thanks to Jonathan Leffler and dyp for tracking down the details.)
Quoting a draft of the C++17 standard:
They are not an optional feature in either language (prior to C++17); all conforming compilers must support them and interpret them as specified by the respective language standard.
For example, if this program:
prints
oops
, then your compiler is non-conforming.But many, perhaps most, C compilers are not fully conforming by default. As long as a compiler can be made to conform to the standard in some way, that's good enough as far as the standard is concerned. (gcc requires
-pedantic
and-std=...
to do this.)But even if a compiler is fully conforming, there's nothing in the standard that forbids a compiler from warning about anything it likes. A conforming C compiler must diagnose any violation of a syntax rule or constraint, but it can issue as many additional warnings as it likes -- and it needn't distinguish between required diagnostics and other warnings.
Trigraphs are very rarely used. The vast majority of development systems support directly all the characters for which trigraphs substitute:
#
,[
,\
,]
,^
,{
,|
,}
,~
.In fact, it's likely that trigraphs are used accidentally more often than they're used correctly:
Warning about trigraphs that might alter the meaning of a program (relative to the meaning it would have if the language didn't have trigraphs) is both permitted by the ISO standard and IMHO perfectly reasonable. Most compilers probably have options to turn off such warnings.
Conversely, for a C++17 compiler that doesn't implement trigraphs, it would be reasonable to warn about sequences that would have been treated as trigraphs in C++14 or earlier, and/or to provide an option to support trigraphs. Again, an option to disable such warnings would be a good thing.