https://stackoverflow.com/questions/7825055/what-does-the-operator-do-in-c Stack Overflow 1. About 2. Products 3. For Teams 1. Stack Overflow Public questions & answers 2. Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers 3. Talent Build your employer brand 4. Advertising Reach developers & technologists worldwide 5. About the company [ ] Loading... 1. current community + Stack Overflow help chat + Meta Stack Overflow your communities Sign up or log in to customize your list. more stack exchange communities company blog 2. 3. Log in 4. Sign up 1. Home 2. 1. Public 2. Questions 3. Tags 4. Users 5. Companies 6. Collectives 7. Explore Collectives 3. 1. Teams Stack Overflow for Teams - Start collaborating and sharing organizational knowledge. [teams-illo-free-si] Create a free Team Why Teams? 2. Teams 3. Create free Team Collectives(tm) on Stack Overflow Find centralized, trusted content and collaborate around the technologies you use most. Learn more about Collectives Teams Q&A for work Connect and share knowledge within a single location that is structured and easy to search. Learn more about Teams What does the ??!??! operator do in C? Ask Question Asked 10 years, 11 months ago Modified 1 year, 1 month ago Viewed 371k times 2440 I saw a line of C that looked like this: !ErrorHasOccured() ??!??! HandleError(); It compiled correctly and seems to run ok. It seems like it's checking if an error has occurred, and if it has, it handles it. But I'm not really sure what it's actually doing or how it's doing it. It does look like the programmer is trying express their feelings about errors. I have never seen the ??!??! before in any programming language, and I can't find documentation for it anywhere. (Google doesn't help with search terms like ??!??!). What does it do and how does the code sample work? * c * operators * trigraphs Share Improve this question Follow edited May 15, 2020 at 2:44 user12211554 asked Oct 19, 2011 at 16:56 Peter Olson's user avatar Peter OlsonPeter Olson 134k4848 gold badges199199 silver badges240240 bronze badges 4 * 61 Sadly this gem of a program won't work in C++17 and newer. - phoenix Jul 15, 2018 at 12:40 * 14 i am going to use this to annoy humans - tycoon Mar 16 at 12:40 * 17 Has Microsoft Windows finally been open-sourced or where did this come from? - Fonic Aug 1 at 13:46 * 4 Trigraphs will be removed in the ISO C23 standard. - Keith Thompson 23 hours ago Add a comment | 4 Answers 4 Sorted by: Reset to default [Highest score (default) ] 1951 ??! is a trigraph that translates to |. So it says: !ErrorHasOccured() || HandleError(); which, due to short circuiting, is equivalent to: if (ErrorHasOccured()) HandleError(); Guru of the Week (deals with C++ but relevant here), where I picked this up. Possible origin of trigraphs or as @DwB points out in the comments it's more likely due to EBCDIC being difficult (again). This discussion on the IBM developerworks board seems to support that theory. From ISO/IEC 9899:1999 SS5.2.1.1, footnote 12 (h/t @Random832): The trigraph sequences enable the input of characters that are not defined in the Invariant Code Set as described in ISO/IEC 646, which is a subset of the seven-bit US ASCII code set. Share Improve this answer Follow edited Aug 19, 2021 at 5:46 Lucas's user avatar Lucas 46622 gold badges1111 silver badges1515 bronze badges answered Oct 19, 2011 at 16:58 user786653's user avatar user786653user786653 28.7k33 gold badges4141 silver badges5151 bronze badges 8 * 516 Trigraphs originally were needed in case you keyboard didn't have eg a '|' symbol. Here it's either the programmer deliberately being annoying or some bizarre editor 'feature' - Martin Beckett Oct 19, 2011 at 17:02 * 34 It's not necessarily EBCDIC - the set of characters that require trigraphs almost exactly matches the set of characters that are not invariant in ISO-646 (i.e. the old 'national ascii' standards). - Random832 Oct 19, 2011 at 18:01 * 90 A perfectly readable alternative would be ErrorHasOccurred() && HandleError(); That is, if you're used to shell scripting. :) - Yam Marcovic Oct 24, 2011 at 15:01 * 12 Just note that many coding standards specifically ban the use of Trigraphs and Digraphs, and many compilers & static analyzers will flag their use. - Luciano Apr 15, 2015 at 15:35 * 10 Not valid since C++17 :| - val is still with Monica Dec 15, 2018 at 17:12 | Show 3 more comments 563 Well, why this exists in general is probably different than why it exists in your example. It all started half a century ago with repurposing hardcopy communication terminals as computer user interfaces. In the initial Unix and C era that was the ASR-33 Teletype. This device was slow (10 cps) and noisy and ugly and its view of the ASCII character set ended at 0x5f, so it had (look closely at the pic) none of the keys: { | } ~ The trigraphs were defined to fix a specific problem. The idea was that C programs could use the ASCII subset found on the ASR-33 and in other environments missing the high ASCII values. Your example is actually two of ??!, each meaning |, so the result is ||. However, people writing C code almost by definition had modern equipment,^1 so my guess is: someone showing off or amusing themself, leaving a kind of Easter egg in the code for you to find. It sure worked, it led to a wildly popular SO question. ASR-33 Teletype ^ ASR-33 Teletype --------------------------------------------------------------------- ^1. For that matter, the trigraphs were invented by the ANSI committee, which first met after C become a runaway success, so none of the original C code or coders would have used them. Share Improve this answer Follow edited Aug 15, 2016 at 18:02 answered Oct 19, 2011 at 21:09 DigitalRoss's user avatar DigitalRossDigitalRoss 141k2424 gold badges241241 silver badges327327 bronze badges 13 * 31 It's not the only case of missing characters, in the keyboard and the character set. The Commodore 64 is likely to be more familiar to a lot of people in their late thirties and upwards - the displayed character sets both lacked braces (and probably the bar and tilde too) - in this case because the "ASCII" wasn't ASCII. In ECMA-6 (almost always called ASCII, but not US-ASCII) there were 18 region-specific codes, but I don't know which codes they were. The one thing I can say for sure - in the British "ASCII", # was replaced with PS. In other regions, maybe "ASCII" had no braces etc. - user180247 Oct 20, 2011 at 4:06 * 8 The similar ATASCII character set for Atari 8-bit computers also lacked { } as well as ~ and `. - dan04 Oct 20, 2011 at 6:16 * 54 See these two Wikipedia articles. I'm just about old enough to still remember the era of 7-bit national charsets (although I'm sure they still linger on in some dark unswept corners), and the book I first learned C from found it necessary to warn about the possibility of if (x || y) { a[i] = '\0'; } looking like if (x oo y) a aAiA = 'O0'; a in the wrong charset. - Ilmari Karonen Oct 20, 2011 at 13:36 * 15 Another interesting historical note is that Unix (which was the big platform C rode in on) may have been the first system of any significance (and maybe the first overall) to default alphabetic values to lower case rather than upper case. Although I haven't seen with my own eyes many contemporary systems, I think this was a real sign of sophistication. Besides being really the only decent OS, Unix also converted your upper case to lower, rather than vice versa. Those guys were really cool. - DigitalRoss Oct 26, 2011 at 2:45 * 26 Funny story I gotta tell ya... the IBM RS/6000 workstation's XL Fortran compiler was developed from the XL C compiler. In the first few releases, they accidentally left in the trigraph processing, so there were some legit Fortran character sequences (in a literal string, IIRC) that were misinterpreted as C trigraphs, leading to some interesting bugs! - Phil Perry Apr 11, 2014 at 18:25 | Show 8 more comments 198 It's a C trigraph. ??! is |, so ??!??! is the operator || Share Improve this answer Follow edited Mar 8, 2017 at 22:15 MD XF's user avatar MD XF 7,60277 gold badges4040 silver badges6868 bronze badges answered Oct 19, 2011 at 16:58 Joel Falcou's user avatar Joel FalcouJoel Falcou 6,14711 gold badge1616 silver badges3434 bronze badges 3 * 13 trigraph come from a period where some keyboard didnt have all the keys they have now. It also hels when some text editor reserved special characters for special things. It's mostly a relic of the past and a quizz enabler ;) - Joel Falcou Mar 23, 2017 at 19:45 * 7 Because some keyboards apparently don't have "|" so some people have no option but to headbutt the keyboard repeatedly until a trigraph occurs that gives them the symbols they need. - Owl Jan 11, 2019 at 18:06 * 3 And then there is the header file. - David R Tribble Oct 25, 2019 at 21:08 Add a comment | 195 As already stated ??!??! is essentially two trigraphs (??! and ??! again) mushed together that get replaced-translated to ||, i.e the logical OR, by the preprocessor. The following table containing every trigraph should help disambiguate alternate trigraph combinations: Trigraph Replaces ??( [ ??) ] ??< { ??> } ??/ \ ??' ^ ??= # ??! | ??- ~ ^Source: C: A Reference Manual 5th Edition So a trigraph that looks like ??(??) will eventually map to [], ?? (??)??(??) will get replaced by [][] and so on, you get the idea. Since trigraphs are substituted during preprocessing you could use cpp to get a view of the output yourself, using a silly trigr.c program: void main(){ const char *s = "??!??!"; } and processing it with: cpp -trigraphs trigr.c You'll get a console output of void main(){ const char *s = "||"; } As you can notice, the option -trigraphs must be specified or else cpp will issue a warning; this indicates how trigraphs are a thing of the past and of no modern value other than confusing people who might bump into them. --------------------------------------------------------------------- As for the rationale behind the introduction of trigraphs, it is better understood when looking at the history section of ISO/IEC 646: ISO/IEC 646 and its predecessor ASCII (ANSI X3.4) largely endorsed existing practice regarding character encodings in the telecommunications industry. As ASCII did not provide a number of characters needed for languages other than English, a number of national variants were made that substituted some less-used characters with needed ones. ^(emphasis mine) So, in essence, some needed characters (those for which a trigraph exists) were replaced in certain national variants. This leads to the alternate representation using trigraphs comprised of characters that other variants still had around. Share Improve this answer Follow edited Jun 20, 2020 at 9:12 Community's user avatar CommunityBot 111 silver badge answered Mar 25, 2016 at 2:24 Dimitris Fasarakis Hilliard's user avatar Dimitris Fasarakis HilliardDimitris Fasarakis Hilliard 141k3030 gold badges248248 silver badges237237 bronze badges 3 * 4 Good explanation.... this also shows why placeholders such as char *date = "??-??-??!" may not produce what you expect (this actually produces char *date = "~~|";) - Andrew Sep 23, 2021 at 9:38 * Seems like most typical C codes would be pretty hard to read if fully implemented using trigraphs: if(data??(x??)??(y??)=='??/r' ??!??! data??(x??)??(y??)==0) ??< break; ??> - wojtow Mar 7 at 19:00 * 1 @wojtow nah, you're just not hardcode enough :) just add some ?: for added readability - quetzalcoatl Apr 8 at 11:33 Add a comment | Highly active question. Earn 10 reputation (not counting the association bonus) in order to answer this question. The reputation requirement helps protect this question from spam and non-answer activity. Not the answer you're looking for? Browse other questions tagged * c * operators * trigraphs or ask your own question. * The Overflow Blog * Meet Saves: the tool to help you organize your favorite content on Stack... * Meet the AI helping you choose what to watch next * Featured on Meta * Bookmarks have evolved into Saves * Recent color contrast changes and accessibility updates * Reviewer overboard! Or a request to improve the onboarding guidance for new... * Collectives Update: Recognized Members, Articles, and GitLab * The [placement] tag is being burninated * Should I explain other people's code-only answers? Linked 66 What is the meaning of `???-` in C++ code? 27 Cryptic line "??!??!" in legacy code 3 Incrementing reference variable doesn't work 3 Why are there alternative tokens in C++? 24 C strange macro syntax 13 Is there a switch to disable trigraphs with clang? 4 Trigraph characters 2 Segmentation fault in number printing program 4 Use of '??=', '??<' and '??>' in c 1 IAR EW for ARM 8.50 and oddball char array literal behavior in C++ See more linked questions Related 2915 What is the difference between #include and #include "filename"? 5651 Which equals operator (== vs ===) should be used in JavaScript comparisons? 7488 Does Python have a ternary conditional operator? 1532 Is there a "null coalescing" operator in JavaScript? 3941 What is the !! (not not) operator in JavaScript? 2010 What is the effect of extern "C" in C++? 9859 What is the "-->" operator in C++? 3248 Improve INSERT-per-second performance of SQLite 4964 Reference -- What does this symbol mean in PHP? 2389 What are the basic rules and idioms for operator overloading? Hot Network Questions * Why doesn't law take into account probability? * Should I give full credit for a correct answer different from the expected one to an exam question? * What is the lift to drag ratio of a human being? * Longest alternating subsequence * With the power to draw you in (and be swept away by the joy of puzzling) * Why did IBM PC have horizontal cursor instead of vertical or block cursor? * What does "grade level" mean? * Why use bar chart with error whiskers instead of box plot? * How to defend allies as a Fighter at level 1? * Calculating the equilibrium value of a discrete time system in matrix form? * Where do you store an airplane for an overnight stop? * Besides Galadriel and Glorfindel, were any of the elves in living in Middle-earth at the end of the Third Age born in Aman? * Is pipe ( | ) a command? * If it takes a very long time to get a referee report, does that mean the referee wanted to sabotage me? * How to express " the lights in the keys of the keypad are on" * So... what happened to the Great Zapfish? * If I quit, can my employer claim back pay that was agreed to but not included in our written contract? * Does Taleb's claim of epidemics with a death count of >1,000 being in the lower hundreds (in the last 2,500 years) seem accurate? * How can I remove this Kwikset entry door dead bolt lock? * Should most Apex tests prove security using runAs() * When to show focus outline * Perfect fit for a grammatical error * What extra number did I form? * How did Gollum follow the Fellowship through Lothlorien without being caught? more hot questions Question feed Subscribe to RSS Question feed To subscribe to this RSS feed, copy and paste this URL into your RSS reader. [https://stackoverflo] * lang-c Stack Overflow * Questions * Help Products * Teams * Advertising * Collectives * Talent Company * About * Press * Work Here * Legal * Privacy Policy * Terms of Service * Contact Us * Cookie Settings * Cookie Policy Stack Exchange Network * Technology * Culture & recreation * Life & arts * Science * Professional * Business * API * Data * Blog * Facebook * Twitter * LinkedIn * Instagram Site design / logo (c) 2022 Stack Exchange Inc; user contributions licensed under CC BY-SA. rev 2022.10.6.30587 Your privacy By clicking "Accept all cookies", you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy. Accept all cookies Customize settings