13

I've got some (legacy) code that I'm building with clang for the first time. The code is something like:

sprintf(buf, "%s <%s ????>", p1, p2);

Clang gives the following warning (error with -Werror):

test.c:6:33: error: trigraph converted to '}' character [-Werror,-Wtrigraphs]
    sprintf(buf, "%s <%s ????>", p1, p2);
                           ^

Clearly the ??> is not intended as a trigraph, so I want to disable trigraphs entirely (the source does not intentionally use them anywhere).

I have tried -no-trigraphs but that's not really an option:

clang: warning: argument unused during compilation: '-no-trigraphs'

I can turn off the trigraphs warning with -Wno-trigraphs but I don't want the trigraph conversion to actually take place at all.

NOTE: Trigraphs were enabled as an unintended side effect of using -std=c89.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 2
    Ouch! GCC has a sensible policy of ignoring trigraphs, even in strict compliance mode, unless you hold its hands to the fire with `-trigraphs`. Time to break out `sed`? Or an equivalent. – Jonathan Leffler Feb 21 '12 at 23:59
  • 3
    Actually GCC's strict compliance modes (`-std=c89`, `-std=c99`, etc) do turn on trigraph conversion. – zwol Feb 22 '12 at 00:04
  • 2
    And if anyone is wondering WTH is a trigraph. [Here's the pony](http://stackoverflow.com/questions/7825055/what-does-the-c-operator-do)... – Mysticial Feb 22 '12 at 00:12
  • They do? [_...pause...conduct experiment..._] Oh, yes, apparently they do. Oh, that's good; it saves me doing a search in my source code, since the stuff works. I'll add `-Wtrigraphs` to my uber-fussy compilation options for a while, or go grepping, I suppose, but I've not seen any problems so it is unlikely to afflict me. – Jonathan Leffler Feb 22 '12 at 00:14
  • 1
    @JonathanLeffler: `-Wtrigraphs` is on by default as long as you *don't* request trigraph conversion (explicitly or implicitly). – zwol Feb 28 '12 at 20:23

2 Answers2

8

Try using gnu* mode - "Trigraphs default to being off in gnu* modes; they can be enabled by the -trigraphs option." (see http://clang.llvm.org/docs/UsersManual.html#c_modes for other differences and command line switch)

yachoor
  • 929
  • 1
  • 8
  • 18
  • Ah, that was it! I was using `-std=c89`, but with `-std=gnu89` I get the message `error: trigraph ignored [-Werror,-Wtrigraphs]` which I can disable with `-Wno-trigraphs`. – Greg Hewgill Feb 22 '12 at 00:11
  • 3
    Is there a way to disable trigraphs without also enabling gnu extensions? – bames53 Apr 10 '12 at 15:25
4

I couldn't see an obvious way to disable trigraphs (rather than the trigraphs warning). Probably the easiest way to fix this code is to change it to:

sprintf(buf, "%s <%s ????"">", p1, p2);
Hugh
  • 8,872
  • 2
  • 37
  • 42
  • That seems like a reasonable option. Out of millions of lines of source, `??>` only occurs four times. – Greg Hewgill Feb 22 '12 at 00:02
  • `"...???\?>"` should also work. Put the backslash between the two question marks of the trigraph itself. – zwol Feb 22 '12 at 00:02
  • Since trigraphs can appear anywhere, maybe `sed "s/??\([-<>()\/=#']\)/?\\?\1/g"` to convert any trigraph into a safe sequence. On the other hand, outside of a string, maybe the trigraph would be best converted to its standard form? It gets a bit tricky to decide what's best. (Just for once, my `sed` script uses double quotes around the pattern, because there is a single quote in the pattern.) – Jonathan Leffler Feb 22 '12 at 00:09