[HN Gopher] Results of the Grand C++ Error Explosion Competition...
       ___________________________________________________________________
        
       Results of the Grand C++ Error Explosion Competition (2014)
        
       Author : st_goliath
       Score  : 159 points
       Date   : 2024-05-06 17:57 UTC (5 hours ago)
        
 (HTM) web link (tgceec.tumblr.com)
 (TXT) w3m dump (tgceec.tumblr.com)
        
       | underdeserver wrote:
       | _Multiplier: 5.9 billion_
       | 
       | That's... several orders of magnitude larger than I'd have
       | guessed.
        
         | ivanjermakov wrote:
         | I guess the limit is the stack size? Would that mean that
         | output error size dependends on compiler flags?
        
         | jepler wrote:
         | I don't know what compiler & flags they ran it on, but with gcc
         | 12's preprocessor it looks much more than that: include files
         | nest to a level of 200 before an error by default. with `-fmax-
         | include-depth=10`, about 200kB of error is printed, and each
         | subsequent level doubles that, so you'd be in for about 3e62
         | bytes of error output by my calculation...
         | 
         | clang 14 terminates preprocessing as soon as any header exceeds
         | maximum nesting, so only ~6kB of errors are produced by it.
        
       | AlotOfReading wrote:
       | I like to increment the most significant digit of my terminal
       | history size every time I run into a compiler error that exceeds
       | the previous value. On Saturday, it went up from 40k to 50k.
       | 
       | I laugh to hide my pain.
        
         | codetrotter wrote:
         | When you get to 100k, will the next increment be to 200k then?
        
           | AlotOfReading wrote:
           | I think the next increment from 100k would be to seriously
           | consider a different language.
        
             | bee_rider wrote:
             | You must have a much more advanced relationship to errors
             | than me. I don't think I could tell the difference between
             | 100k or 40k lines worth of errors, and it was only halfway
             | through writing this message that I realized you might
             | actually be talking about the size of _an_ error? Oh no.
        
               | Twisol wrote:
               | I suspect you'd notice simply because scrolling to the
               | top of your history isn't sufficient anymore to find the
               | first error. (Assuming one clears their shell history
               | before compilation, which is very nearly required in this
               | context...)
        
         | lqet wrote:
         | I tutored a C++ beginners course on Linux a few times. I have
         | had people ask me for help because the error messages were so
         | long, their terminal history wasn't large enough to scroll back
         | to the first error. Even if you have basic bash skills, just
         | piping the compiler output to less or head also doesn't work,
         | because the errors go to stderr. It's an incredible source of
         | frustration for beginners.
        
           | wglb wrote:
           | Wouldn't it work if you did                 2>&1
           | 
           | as part of the redirect?
        
             | rocqua wrote:
             | Yes, but if someone only just learned about less and
             | piping, they probably won't know about fd 2 being stderr,
             | fd based redirection, and hence don't understand it at all
        
             | paulddraper wrote:
             | Yes, but most beginners have never seen (or remember) that.
        
             | jprete wrote:
             | I know about that mechanism but I use it so infrequently
             | that I have to look it up every time; the syntax doesn't
             | really match anything else I know. It's also hard to look
             | up because even the right search terms fetch a lot of
             | nearby-concept results so I have to dig for the exact idea.
             | 
             | (Probably this is an ideal LLM question though!)
        
           | bogwog wrote:
           | Konsole's default scroll-back is 1000 lines. I wonder what is
           | the simplest, most realistic error a beginner would encounter
           | that exceeds that?
        
           | usefulcat wrote:
           | > just piping the compiler output to less or head also
           | doesn't work, because the errors go to stderr
           | 
           | |& is your friend:
           | 
           | g++ foo.cc |& less
        
           | jiggawatts wrote:
           | If only there was some sort of invention that could be used
           | to replace a virtual teletypewriter that could somehow parse
           | the error messages and put them into a convenient list that
           | could be navigated using simple visual paradigms instead of
           | bits and pieces of a shell scripting engine... /s
        
           | jcelerier wrote:
           | > I tutored a C++ beginners course on Linux a few times. I
           | have had people ask me for help because the error messages
           | were so long, their terminal history wasn't large enough to
           | scroll back to the first error.
           | 
           | A non-problem if you use any IDE which has been able to group
           | error under foldable menus (such things have existed on Linux
           | for longer than some of the people you are teaching may have
           | been on this planet)
        
         | queuebert wrote:
         | Pipe to command-line LLM: https://justine.lol/oneliners/
        
         | renox wrote:
         | |& tee <log file> is your friend.
        
       | gsliepen wrote:
       | 10 years afterwards and GCC still produces the huge error
       | messages. It seems Clang is now smart enough to stop compiling
       | after too many errors.
        
         | gmueckl wrote:
         | GCC also has (had?) an error limit. But because C++ compilers
         | like to show you actual backtraces of how template
         | instantiations led to the error condition, each single error
         | message can easily have dozens of lines of context. That's how
         | I got GCC to output 1MB of text for a single typo and the
         | following parser confusion.
        
       | hughw wrote:
       | I've mostly become adept at traversing six mile long compile
       | error crawls to find the bit in my code causing the STL/Thrust
       | complaint. clang is more legible for this than gcc. Still, I keep
       | learning new patterns.
        
       | WalterBright wrote:
       | The D language compiler uses a technique I call "poisoning" which
       | has greatly reduced cascading error messages. The idea is
       | whenever an error is found in an AST node, the AST node is
       | replaced with an "error" node. Any combination of an error node
       | with another node is replaced with an error node. Error messages
       | for error nodes are suppressed.
       | 
       | It works far better than attempting to repair the AST into some
       | plausible state.
       | 
       | It's analogous to the propagation of NaN values in floating point
       | code.
        
         | jansvoboda11 wrote:
         | Do you cut off this poisoning at any point?
        
           | WalterBright wrote:
           | If something else depends on the successful semantic analysis
           | of those poisoned nodes, they get poisoned as well. It's all
           | based on dependency.
        
         | tester756 wrote:
         | But with this approach you arent able to provide e.g
         | intellisense or other IDE hints for valid things within this
         | node, right?
        
           | WalterBright wrote:
           | A hint can be provided where the original error is diagnosed.
           | I doubt hints on cascaded errors would be of any use.
        
             | tester756 wrote:
             | if you have function like
             | 
             | "public intd Test() { ... typing new line }"
             | 
             | then you will not provide hints when writing that new line
             | due to "intd" being invalid type?
        
               | WalterBright wrote:
               | A function's declaration is not affected by its body, so
               | that shouldn't be a problem.
        
           | tnh wrote:
           | Things _within_ the node are fine because errors propagate
           | upwards. The problem is things like:                   Foo
           | getFoo(int);         getFoo().???; // want code completion!
           | 
           | `getFoo()` is missing an argument, but you still want to
           | complete Foo's members. If you type `getFoo().getBar()` you
           | want go-to-definition to work on `getBar`.
           | 
           | In clang, we use heuristics to preserve the type in high-
           | confidence cases. (here overload resolution for `getFoo`
           | failed, but there was only one candidate function). This
           | means you can get cascading errors in those cases (but often
           | that's a good thing, especially in an IDE - tradeoffs).
        
         | munificent wrote:
         | I've got a compiler for a hobby language that uses this
         | technique too (I probably got it from you, unless I heard it
         | from someone else). It's really really nice. Super easy to
         | implement and really does cut down on cascaded errors.
         | 
         | I also use it during type checking. There is a special "error"
         | type. If an expression produces a type error, the yielded type
         | of that expression becomes "error". Surrounding expressions
         | that consume that type will see the error type and suppress any
         | other type errors they might otherwise produce. That way, you
         | only see the original type error.
        
           | WalterBright wrote:
           | Yup, dmd also has an error type:
           | 
           | https://github.com/dlang/dmd/blob/master/compiler/src/dmd/mt.
           | ..
        
           | nathan_douglas wrote:
           | Funny, I was just gonna comment and say that I learned this
           | One Weird Trick... and then realized I'd learned it from you.
           | 
           | (Hi, Bob! I was actually just using your recursive
           | shadowcasting algorithm as a reference yesterday.)
           | 
           | I feel like I just got an Erdos number or something.
        
           | tnh wrote:
           | > Surrounding expressions that consume that type will see the
           | error type and suppress any other type errors they might
           | otherwise produce.
           | 
           | We added a slightly-cursed version of this to clang. The goal
           | was: include more broken code in the AST instead of dropping
           | it on the floor, without adding noisy error cascades.
           | 
           | The problem is, adding a special case to all "surrounding
           | expressions that consume that type" is literally thousands of
           | places. It's often unclear exactly what to do, because
           | "consume" means so many things in C++ (think overload
           | resolution and argument-dependent lookup) and because certain
           | type errors are used in metaprogramming (thanks, SFINAE). So
           | this would cost a lot of complexity, and it's too late to
           | redesign clang around it.
           | 
           | But C++ already has a mechanism to suppress typechecking!
           | Inside a template, most analysis of code that depends on a
           | template parameter is deferred until instantiation. The
           | implementation of this is hugely complicated and expensive to
           | maintain, but that cost is sunk. So we piggy-backed on this
           | mechanism: clang's error type is `<dependent type>`. The type
           | of this expression depends on how the programmer fixes their
           | error :-)
           | 
           | And that's the story of how C gained dependent types
           | (https://godbolt.org/z/szGdeGhrr), because why should C++
           | have all the fun?
           | 
           | (This leaves out a bunch of nuance, of course the truth is
           | always more complicated)
        
       | cgh wrote:
       | Some of the category descriptions are great, eg for "Most
       | lifelike":
       | 
       | Suppose you are given a task of adding some new functionality to
       | an existing code base. You have been told that the guy who wrote
       | it was "really smart" and that his code is of "enterprise
       | quality". You check out the code and open a random file in an
       | editor. It appears on the screen. After just one microsecond of
       | looking at the code you have lost your will to live and want
       | nothing more than to beat your head against the table until you
       | lose consciousness.
       | 
       | This entry could be that code.
        
       | axra wrote:
       | This is super interesting. I will do a 2024 edition.
        
       | lqet wrote:
       | The difference between an experienced C++ programmer and a C++
       | novice is that the novice regularly believes that his code _is
       | broken beyond repair for eternity and has accidentally destroyed
       | the compiler and most of the hard drive_ , while the former just
       | yawns at 5,000 lines of error messages and adds the missing
       | semicolon.
        
         | erikerikson wrote:
         | As an experienced c++ programmer, I just write TypeScript
         | without semicolons. /troll?
        
         | baq wrote:
         | Just 5000? Things must've gotten much better since I last
         | touched C++
        
           | marcosdumay wrote:
           | It's just a semicolon. The GP still didn't fix enough to get
           | to the templates and linker errors.
        
         | secondcoming wrote:
         | For me these days the most unintuitive error messages are due
         | to a missing `const`
        
       | jcalvinowens wrote:
       | Generally speaking, clang produces much clearer C++ compile
       | errors than gcc. I can't give any specific examples off the top
       | of my head, but I've seen GCC emit hundreds of lines of
       | inscrutable errors where clang spits out one line that tells you
       | exactly what is wrong.
        
       | maxlin wrote:
       | What's the point in not showing the actual results? Is the
       | expectation really to have a compiler handy just to browse the
       | results
        
         | omoikane wrote:
         | Did you mean the page not showing the generated error messages?
         | The actual error messages would be many gigabytes worth of
         | text, and aren't as interesting as the entries that produced
         | those error messages.
        
         | kccqzy wrote:
         | The multiplier is in the billions. The actual results are
         | gigabytes large. Your browser cannot handle that.
        
           | klyrs wrote:
           | Even if your browser can handle it, tumblr doesn't wanna
           | serve it.
        
             | kevindamm wrote:
             | Even if Tumblr wanted to serve it, who would want to
             | download it!? although it probably deflates really well.
        
       | quotemstr wrote:
       | Has anyone tried these code snippets on modern compilers and
       | noted how much our error messages have improved?
        
       ___________________________________________________________________
       (page generated 2024-05-06 23:00 UTC)