Trigraphs

How would you like the next piece of code?

??=include <iostream>
??=define A "hey"

int main () ??<
    char x??(??) = A;
    if (0 ??' 1)
        std::cout << x << std::endl;
    // what do you say about this code??/
    std::cout << "amusing" << std::endl;
??>

This is actually a legitimate sourcecode. It generates a single output line of “hey”.

This code uses a C++ feature called trigraphs, documented here. The trigraphs are present in the language for reasons that were (possibly) more common in the past; If you didn’t have all the characters on the available keyboard, you could use these trigraphs to represent the characters you were lacking. I believe this issue is not a major problem nowadays.

The real crazy thing about this option is that, it’s enabled in Visual Studio (2008) by default! I’m sure that if I wrote the following line

std::cout << "testing123??!" << std::endl;

and got the output below

testing123|

I wouldn’t know what hit me.

I’d like to add that trigraphs are disabled in gcc (and g++) by default, but can be enabled by using the –trigraphs switch, which makes far more sense than having them enabled by default.

One extra important piece of information regarding this issue is that, according to Wikipedia, trigraphs are the first thing that gets replaced by the preprocessor – before any other processing is done. This property can be observed in the example, where even occurrences of trigraphs within strings got substituted. Be very careful when using two consecutive question marks!

7 thoughts on “Trigraphs

  1. This one seems excessively silly. Why would they still be enabled by default anywhere?
    It’s even worse when you consider that if your advice would have been ‘turn off trigraphs in vs2008’, then people would have been bitten when porting, or just copying the code somewhere.

    Also, it seems disabling them in vs2008 is not trivial (they are not in the preprocessor list of config options). Stupidity at work I guess.

    1. I couldn’t agree more.

      However, I think that disabling this would cause virtually no porting problems since I really doubt that there’s a significant amount of code using these “features” – and if there is, it’s pretty easy to find (very small number of sequences to search & replace if needed). So here’s a call to Microsoft to disable this in the next Visual Studio release.

      1. I’m not sure you got my meaning.
        Let’s say that I have a piece of code that has trigraphs in it. Maybe because I did so ahead of time, or maybe because I found out about it, I cancel trigraphs in vs.
        Later on, someone else uses my code, but in a new project. He will get bitten by trigraphs as well.

        Of course, it will happen to him the same way if he ports code from gcc.

        1. You are considering this from the side of someone who decides not to use this option by disabling it in his compiler, while i was referring to the case where someone actually wanted to use it.
          In your scenario I would say that anybody that is aware of this feature should not rely on it being disabled – any such programmer must be careful when programming. For example, escape _every_ second consecutive question mark (“??!” etc). Thats why we have an escape sequence for the question mark.

    1. The sad thing is that Trigraphs are enabled in VS2008 by default.
      I have just checked the code under VS2008 and it works as expected. The (whole) blog has been altered to use the [/sourcecode] tags, so copy&paste should go alot smoother now. Let me know if you have any more issues.

Leave a Reply