top | item 21795644

C, what the fuck??!

73 points| bowero | 6 years ago |bowero.nl

36 comments

order

zeotroph|6 years ago

This is about that ancient EBCDIC (IBM's ASCII "competitor") specific hack called trigraphs, which in modern compilers are opt-in anyhow: "To understand this, I have to admit one thing: I have to pass -trigraphs to a modern version of gcc before this actually works. "

C++17 actually removed support for these.

fanf2|6 years ago

Trigraphs were not specific to EBCDIC: they were also a bad accommodation for the ISO 646 ASCII variants that supported European languages, which used characters {\|} etc. for letters. This is why the newer better header with alternate spellings for restricted character sets is called <iso646.h>

https://en.wikipedia.org/wiki/ISO/IEC_646

segfaultbuserr|6 years ago

Digraphs were supposed to be a easier-to-read alternative to trigraphs. Unfortunately, the extended list of digraphs with many additional logic operators by C++ never entered C, i.e.

    %:%:    ##
    compl   ~
    not     !
    bitand  &
    bitor   |
    and     &&
    or      ||
    xor     ^
    and_eq  &=
    or_eq   |=
    xor_eq  ^=
    not_eq  !=
C only has basic ones (still more intuitive than trigraphs).

    <:  [
    :>  ]
    <%  {
    %>  }
    %:  #
Last time, I had to type a C program on a touchscreen, and those symbols were extremely difficult to enter. I knew digraphs can help, but then realized that I couldn't use the digraphs for logic operators without programming C under C++.

hvdijk|6 years ago

C has the named operators as macros in <iso646.h>.

pwdisswordfish2|6 years ago

TL;DR: Trigraphs. That at least makes the ā€˜??!’ in the title meaningful.

It's still clickbait, though.

krzat|6 years ago

Especially that it requires enabling a compiler flag. If you need to require that then you could require "#define true false" as well.

threatripper|6 years ago

What is the probability of something like this appearing in a normal program written by somebody who is unaware of trigraphs?

I am also not aware of any professional who would use multiple question marks in any kind of serious code that could be read by anybody else because that kind would reflect negatively on the perception of his professionalism.

stephen_g|6 years ago

The article mentions that they had to explicitly enable it with a compiler flag to get it to work. I doubt any modern compiler would still support these by default.

bowero|6 years ago

The chance of this accidentally happening is almost 0. This is what `gcc` does:

`test.c:6:31: warning: trigraph ??/ ignored, use -trigraphs to enable [-Wtrigraphs]`

pksadiq|6 years ago

> What is the probability of something like this appearing in a normal program written by somebody who is unaware of trigraphs?

A good compiler (eg: gcc) will warn if any token is interpreted as a trigraph

Edit: digraph works a bit differently [0]

[0] https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C

hvdijk|6 years ago

Nice "No true Scotsman" logic there. Sure, if you see multiple question marks as an indicator of unprofessionalism, then by definition, no professional would use that. At the same time, your definition of professional is not one that is useful in any other context.

In code written by people whose job it is, in part, to write code, i.e. what I would call professionals, multiple question marks do sometimes occur.

spacemanmatt|6 years ago

Pro dev here. I am working on a codebase that is large and juvenile. The original authors didn't know about functions or something; it's pure spaghetti PHP.

I definitely add comments with tons of questions and potential trigraphs when I use punctuation in lieu of actual cursing. Don't get me wrong. I curse a lot in comments, too.

TL/DR: bad code -> angry comments

kosma|6 years ago

The author purposely misleads the reader by doing syntax highlighting wrong. A trigraph-aware editor would keep the third line green.

spacemanmatt|6 years ago

Plot twist: Many developers are using editors that are not trigraph-aware.

mekazu|6 years ago

> Therefore, this line actually says:

    !didIMakeAMistake() || CIsWrongHere();
> If you understand how short-circuit evaluation works, you can understand that this will result in the following:

   if (!didIMakeAMistake()) 
      CIsWrongHere();
Can someone explain this? I’d have thought that was right without the !

segfaultbuserr|6 years ago

It must be a typo.

Function calls have the highest priority here, followed by logic NOT and logic OR.

    !didIMakeAMistake() || CIsWrongHere();
!didIMakeAMistake() is evaluated first (or you can say didIMakeAMistake() is executed and evaluated first, then its result is inverted and checked), if it's true, evaluation is finished. If it's false, CIsWrongHere(); is evaluated.

It is indeed equivalent to

   if (didIMakeAMistake())  /* !didIMakeAMistake() == false? */
      CIsWrongHere();
Without the invertion.

purplezooey|6 years ago

Well, I did always think less of people who // wrote comments like this????

Yuioup|6 years ago

Seriously, at this point C should be considered dangerous and should be actively discouraged. I would even go so far as to legislate it. We can't have this sort of thing in 2019.

jandrese|6 years ago

We don't really have this in 2019. All modern C compilers disable trigraphs by default, so you have to go out of your way to see this in person.

They only existed because really old terminals sometimes didn't have various punctuation characters used by C so they needed the ugly workaround so people trapped on those terminals wouldn't be left out in the cold.

carlmr|6 years ago

The sad thing is that in safety critical embedded systems often the only choice you have is C and C++ because nobody would shell out for ADA developers. Rust would be a contender as well, however I'm not sure how many embedded targets that aren't major (like arm) even have a target.

0xdead|6 years ago

Please don't comment on the state of programming in 2019 if you're an Angular developer.

bowero|6 years ago

I would definitely vote for you.