Pleasant and helpful error messages

By Shamus Posted Wednesday Oct 1, 2014

Filed under: Programming 132 comments

This was originally a commentary on the talk by Jon Blow about creating a programming language designed specifically for games. At one point he mentions “Pleasant and helpful error messages” and I got caught up thinking about what that would really entail. So let’s talk about compiler errors.

Compilers are very bad at giving us useful error messages. I’ve been doing this for decades and I still get errors that baffle me. You could make the case that “better error messaging” could be a whole project in itself. You could keep yourself pretty busy by just ditching the whole “new language” idea and just attempting to give the C++ compiler more useful output. (Although that’s probably a bad idea, for reasons I’ll talk about below.)

There are errors that don’t make sense and point to things that aren’t the source of the problem. They also lean really heavy on the jargon. This is a subject near and dear to my heart. I mean, this article exists because I have this compulsion to help other people understand difficult things.

Lots of people point to templates and classes as a source of baffling messages. But rather than dive into the deep parts of the language or pick on some goofy obscure edge-case, let’s look at a really simple error:

1
2
3
4
5
  float speed;
 
  speed = DoMovement ();
  if (speed >> 8.0f)
    speed = 8.0f;

So DoMovement () sets our speed (don’t ask me what this program does) and then we attempt to limit that speed by not allowing it to go above 8. The problem here is on line 4. There should only be one > symbol there. By putting two, the compiler thinks I’m trying to bit-shift speed by eight placesThat is, move all its binary digits – all those 1’s and 0’s – to the right. It’s like moving the decimal point in a regular number. instead of compare it to the number eight. This generates four errors:

IntelliSense: expression must have integral or unscoped enum type
IntelliSense: expression must have integral or unscoped enum type
error C2297: '>>' : illegal, right operand has type 'float'
error C2296: '>>' : illegal, left operand has type 'float'

Okay, the first two errors come from IntelliSense and not the compiler itself. (I think.) But that doesn’t matter for the purposes of this discussion. The point is that these messages are a very odd and obtuse way to explain these errors. This is not how a human being would describe these problems, unless they were deliberately trying to annoy you. It’s like someone saying, “The fuel reservoir has insufficient material to enable combustion” instead of saying “Your car is out of gas”. Yes, a programmer who knows what they’re doing should be able to parse that, but it’s not an optimal way to communicate. If nothing else, it’s needlessly longer.

Image unrelated.

I’m betting some coders will tell you “It’s not the compiler’s job to teach you how to program,” and “You’ll learn to recognize the error messages eventually.” But I don’t think it really works that way. I very rarely look at the error messages to see what I did wrong. They’re verbose and difficult. I just double-click on the error and examine the line of code it takes me to. I don’t read the message because it’s usually a waste of time and I can spot the problem myself faster than I can untangle the addled compiler output. It’s not that experienced programmers learn to understand the compiler better, it’s that we get enough experience that we no longer need to read its output to spot problems.

I don’t know. Maybe it’s me, but I never find much value in the message except to tell me where the problem is. Consider the above error:

error C2297: '>>' : illegal, right operand has type 'float'

A human would probably say, “You can’t bit-shift with float values.” That’s probably too informal for a compiler, but it’s closer to useful than the one we have now. When I parse this, I stop reading when I see the phrase “right operand” and go back to looking at the code. The error message could be changed to “the right operand is a dumb butt-head loser” and I probably wouldn’t even notice.

The above example is a terrible message because it doesn’t explain what it THINKS you’re trying to do, and it doesn’t say why the operation is illegal. If you’re still thinking that you only typed one > symbol, then you’ll be baffled. What? It’s illegal to compare a float? Since when? If the phrase “bit-shift” was in there you’d be much more likely to notice your typo, because it would draw attention to the operator instead of the operand.

Image unrelated.

Having said all this, I’ll admit it’s a tough problem to solve. I don’t know who composes error messages now, but I’m willing to bet that:

  1. They know the language very, very well. So well that really complex stuff can seem trivially “obvious” to them.
  2. They are an engineer, and were chosen for their technical prowess, not for their communications skills.

It would take a ton of work, and it’s not clear what the gain would be in a purely productivity standpoint. Just saying, “It would be nicer and I would like it more” sounds like a weak justification for making sweeping changes to compiler output. It’s certainly not something people would tolerate in a mature language like C++. Giving the compiler “more friendly” error messages now would probably do more harm than good. Sure, the inexperienced would have an easier time, but the mature coders – the people currently doing real work – might have their workflow disrupted. (Unless they’re like me and read the code instead of the error.) And that’s never a worthwhile trade-off.

But I think “more readable errors” is a noble goal for a new language.

If you want to get all new-age touchy-feely, you could even have errors with optional expanded explanations that link to the language’s wiki. And then you really could have a compiler that could teach you the language. And that would be pretty cool.

 

Footnotes:

[1] That is, move all its binary digits – all those 1’s and 0’s – to the right. It’s like moving the decimal point in a regular number.



From The Archives:
 

132 thoughts on “Pleasant and helpful error messages

  1. Exasperation says:

    Interestingly, this is the second blog post I’ve read today about the need for improved compiler error messages (admittedly, the other post was a couple of weeks old; I just happened to read it today before I checked here).

    1. Ingvar M says:

      Just checked what the Go compiler says.

      For “256 >> 8.0” it silently coerces the float to an int.
      Stuffing 8.0 in a variable results in:

      prog.go:9: invalid operation: 256 >> shift (shift count type float64, must be unsigned integer)
      [process exited with non-zero status]

      And something analogous to the original code results in:

      prog.go:9: non-bool 256 >> 8 (type untyped number) used as if condition

  2. Tse says:

    Wow, SAP has some really helpful error massages in comparison. Errors are always in whole sentences and quite verbose. Too bad it’s almost impossible to get free legal access to a SAP system without working for a company that uses one.

    1. DrMcCoy says:

      Also, SAP is a devilspawn out of the deepest pits of hell…

      1. swenson says:

        It is, it is.

        1. Tse says:

          SAP is my first programming environment and ABAP is my first programming language. So far, I haven’t noticed anything too bad about SAP on its own, but I don’t have anything to compare it to. I’m really interested in the differences with other languages and what their advantages are.

          1. Humanoid says:

            By coincidence I’ve mostly been absent from regular commenting lately because I’m on a SAP ABAP course right now. Urrrrgh.

    2. swenson says:

      Also, occasionally the errors are in German.

      1. Tse says:

        Worse, a lot of the tickets are in German.

        1. Mephane says:

          Worse, just this week I have seen a C++ function name written in German. More precisely – and this is even worse – it was a mixed language name, as if the author just did not know the English translation of a single word and could not even be bothered to spend 10 seconds to google the translation.

          P.S.: I always cringe when workshops and tutorials that are held in German present example code using German function, variable and class names. I mean, ANY proper target audience would understand English anyway, and not have to parse the awkward English/German amalgam that inevitably results from this.

          1. Curse those foreigners, going around speaking other languages. They just do it to annoy you.

          2. Mrcl Pfffr says:

            German coder here. Every German textbook on programming or course I know so far recommends writing all your variables, functions, comments etc in English. But what to do when you have to work with someone who is not good at English? Better have meaningful German language in code then English code no one can read afterwards.

      2. Mephane says:

        Probably your Windows and/or Visual Studio is installed in German, since some of the more system level messages like “file not found” are automatically given in the OS language in such cases.

        1. Tse says:

          The SAP client receives these messages from the server. They’re OS independent.

  3. Alex says:

    Also bear in mind that the error messages are not likely to be single entities, but rather constructed from parts. In the example you give:

    error C2297: ‘>>’ : illegal, right operand has type ‘float’

    “error C2297”: That’s fine, we want a unique language-independent way to refer to these that’s easy to search for online.

    “‘>>'”: It then tells you what operation has the error. It could try and translate this and call it ‘bit shift’, but it’s reasonable to assume that if you wrote the code, you know what it is. And if you don’t, then you’re unlikely to find ‘bit shift’ much more meaningful than ‘>>’ anyway.

    “illegal”: Could be made less formal, I suppose, but there’s only one bit of information to impart here, which is that that operator can’t be used that way.

    “right operand has type ‘float'”: This is why >> was illegal. You could come up with a less formal name for “right operand”, or at least more verbose, but really this does describe what’s wrong fairly well, I think.

    The problem is that you don’t want to know what’s the error is, you want an analysis of what the difference between what you meant and what you wrote is! That’s a far fuzzier sort of problem. Some static analysis tools have a go at it, but to do it well… well, that way lies AI!

    1. 4th Dimension says:

      The problem is the text itself is written in a wierd too formal way. The operation ‘<<' does not accept 'float' as it's right parameter/value/operand, or similar would keep it's ability to be reconstructed to fit other operands but to me it would be easier for somebody to parse that the text "MEANS".

    2. William Newman says:

      “‘illegal’: Could be made less formal, I suppose”

      I don’t know about this particular compiler, but in many compilers there are families of complaints along the lines of “[this is] illegal [code]”, “[the compiler is] warning [you about this code]”, and “[this code has caused the compiler to suffer an] internal error [because something happened in compilation that could only be a bug in the compiler]”. In Common Lisp (not the best-known language to most readers, I know, but one in which I myself happen to worked on the guts of a compiler) some aspects of such families of compilation problems are even specified in the published standard.

      E.g. “The secondary value, warnings-p, is false if no conditions of type error or warning were detected by the compiler, and true otherwise.”
      (in http://www.lispworks.com/documentation/HyperSpec/Body/f_cmp.htm#compile)

      This doesn’t necessarily make it pleasant or friendly, or eliminate jargon, but at least it helps systematize the jargon so that that bit of an error message (distinguishing an full-blown error from a warning, e.g.) can be sharply meaningful.

  4. Michael says:

    I write a compiler. Error messages are really, really, really hard, not because you can’t think of something to say, but because the machine can’t figure out what you were trying to do. The point where it realises something is wrong can be well after the site of the error you actually made, and often there are multiple things you could have meant along the way. The information it has available generally isn’t enough to say what’s wrong definitively, especially for syntax-like errors.

    The tech writer side of things gets a lot of effort in the major compilers, actually, but they can only work with the errors that have been detected, and within the bounds of what that detection is able to say. It’s much worse to be wrong than obtuse, particularly for novices. Producing a message with the wrong diagnosis sends them down the wrong path indefinitely.

    Detecting errors better and reporting them in better ways (graphically, interactively, etc) is a pretty active area of academic research that will maybe make it into the real world eventually.

    1. Zukhramm says:

      I don’t think this specific example needs much work. All the information is already there, the only issue is presentation. Move the operator so that it occurs in the middle of the message instead of before it, and maybe keep a list of translations from the operators as written in C++ to English.

    2. Alex says:

      At least in this case, you don’t need your compiler to know what you’re trying to do. Just translating what you are doing from Compilerese to English and parroting it back would show you what you’re doing wrong, by letting you know you “said” ‘bit shift’ when you meant to say ‘greater than’.

      1. Richard says:

        Except that “>>” isn’t necessarily bit-shift.

        “>>” has two widely-used meanings:

        1) “Bit-shift the left-hand value to the right by the right-hand value”

        2) “Stream the input data source on the left side into the output data sink on the right side”

        It may do something else if the operands have defined something else for “>>” to do (“overloaded” it*.)

        All the compiler knows is “You can’t do ‘>>’ with one of those on the left and one of those on the right”

        * Operator overloading allows you to make any operator do anything to anything.

        This is a GOOD THING, because it lets you write code like:

        if (MyCleverItemA == MyCleverItemB) {do something useful}

        – Overloading the comparison operator to let you easily check if two of your CleverItems are the same.

        Done wrong, operator overloading is also the most hideous hideous thing ever encountered in the history of hideousness.

        But I would not want to be without it.

        1. Zukhramm says:

          I don’t know what actual C++ programers think but to me, overloading >> and << for streams really seem like the exact thing you really shouldn't user overloading for. I mean, overloading + and * for your vector types is one thing because you're implementing sort of equivalent operations but using the same symbol for something completely different feels really ugly to me.

          1. Ithilanor says:

            I don’t know what the initial reasoning behind that choice was, but at this point it’s deeply baked in to the language. C++ has a whole assortment of issues, as people have alluded to here.

          2. Alex says:

            So I actually decided to go back to school and do some simple course work in CS and I gotta say that this is really what puts be off of C++. We have to study both Java and C++ and I have a tendency to favor Java, because of the slightly more verbose general syntax. Having a whole line look like symbol gibberish is not as common in Java and I find it just easier. C++ on the other hand seems very much rooted in having everything abbreviated by symbols and it can make it pretty hard to pick up.

            1. Geebs says:

              A line of indecipherable gibberish full of operators that aren’t doing what you think they should be doing and variables denoted by a single letter (which is the first letter of the most generic construct possible which even slightly relates to what the variable actually is) is what C programmers mean when they say something is “readable”.

              1. Zukhramm says:

                Please don’t associate C programmers with C++ programmers.

            2. Septyn says:

              I have written precisely 4 applets in Java. But coming from the Information Security side of the CS aisle, I have 3 things to say:
              1. Don’t write in Java. Just stop it. Maybe if you stop, Oracle will stop adding “features” and changes that allow attackers to break out of the sandbox.
              2. If you do write in Java, don’t force a specific version on people. Write your code to not only be platform- but version-independent.
              3. If you have to write in a specific version, package that damn thing with a private install of Java. Your “doesn’t play well with others” app shouldn’t force the whole computer to suck at the teat of a vulnerable version of that bastard language.

              I’m only posting this because I’m bitter. And because I have an enterprise with 50,000 computers running JRE 1.6.0.26 that client services refuses to update “because we can’t”.

              Rage……subsiding…..need shwarma.

          3. Recf says:

            In an effort to make the multiple uses of the <> operators make sense, I tend to think of them as the “shove” operators.

            Shove the bits of an int X places to the left
            Shove data into an output stream
            Take data from an input stream and shove it into a variable

            Ruby, if I remember right, uses this for arrays as an alias for .append().

            Personally, if I were designing a language, the bit-shifting an int is the only use case I would have an operator for. I’d prefer actual methods for the other cases. But you can make it make sense if you have to.

    3. The compiler doesn’t have to attempt to translate what YOU “meant”. It has to clearly communicate what it winds up THINKING you meant. In this case, the compiler “thinks” you “meant” “bit-shift this variable”, which is illegal. So something like:

      “cannot >> this variable, illegal type” would be fine. And short. And easy to parse.

      That’s really all the error needs to be. Heck, that’s what all compiler errors ultimately boil down to: “I can’t do what you told me to do because it makes no sense”. So that’s how the error should read. “Can’t perform operation X because Y”.

      1. harborpirate says:

        ^This, exactly.

        If the compiler author wanted to be more verbose, simply expand this:

        “Cannot use operator ‘>>’ on operand ‘8.0f’, illegal type.”

      2. Df458 says:

        The problem is that the compiler doesn’t know that. The compiler just knows that it doesn’t have any operations that take the operands given. After all, the >> operator doesn’t necessarily bit-shift, that’s just what we generally assume it to be.

        I haven’t personally looked at how compilers resolve operators, but I’d guess it’d be pretty hard for a compiler to make a definite link between this case and bit-shifting.

        1. guy says:

          Strictly speaking, a compiler doesn’t resolve an operator as such. It’ll resolve ‘>>’ to DOUBLE_RIGHT_ANGLE_BRACKET or something, then resolve the sequence int DOUBLE_RIGHT_ANGLE_BRACKET int to BitwiseShift.

        2. harborpirate says:

          Compilers first tokenize the input (lexical analysis), and then check the correctness of the input (syntactic analysis).

          This is like figuring out what the words and punctuation must be in a potential sentence, and then doing grammatical analysis to make sure that sentence makes sense.

          In this second stage, we can think of this line as having already been broken into six tokens:
          1. if, a token that indicates an expression will be evaluated
          2. open paren, a token that indicates the start of an expression
          3. speed, a variable known to be a float type
          4. >>, an operator with an overloaded meaning
          5. ‘8.0f’, an implicit declaration of a float type
          6. close paren, a token that indicates the end of an expression

          The two valid grammatical uses that I’m aware of for the >> operator are:
          1. Arithmetic shift (bitwise operation)
          2. Insertion (stream operation)
          The compiler is also aware that these are the only two correct uses of that operator, otherwise it could not do its job.

          In neither case is a float type a valid token in the left position, and though the insertion operation takes an object as the right operand, it can figure out that a float type (a primitive) is also an invalid token in the right position.

          Therefore the message “Cannot use operator “˜>>' on operand '8.0f', float is an illegal type.” should be trivial to generate, since all the information to do so is available to the compiler at that time. Sure, it doesn’t know if you meant to do a bitwise operation or not, but that doesn’t matter, it just needs to spell out your mistake more clearly.

          The key is providing both the operator and the token on which it is operating in the message! The type is much less important (though it should be included as well and you’ll note I changed that in this iteration). There are somewhere between dozens and thousands of variables in most programs, and a programmer is never going to think of a particular one by seeing what type they are. (Requiring extra mental hoops to jump through by looking at the line, seeing that ‘8.0f’ is the right operand, knowing that’s a float, then looking carefully at the operator and noticing its a >>. Whoops.

          As long as it tells you “hey you can’t do >> on ‘8.0f’, which is a float”, it connects all the dots and decreases “mean time to fix”.

  5. I am NOT an expert programmer by far, and I am still learning (typing this in my programming class actually), but I agree that when you are learning and you run into errors like that it’s extremely frustrating, especially when the code looks like it should work!

    I’m sure even programmers who are considered experts in their language have not yet used bits of it for one reason or another, and would themselves benefit from more helpful error messages.

    1. Alex says:

      “I am NOT an expert programmer by far, and I am still learning (typing this in my programming class actually), but I agree that when you are learning and you run into errors like that it's extremely frustrating, especially when the code looks like it should work!”

      Even worse is when the code does allegedly work. Downloading the source code for an open source program you want to modify or an example program from a tutorial and having it fail to compile is one of the most frustrating things that can happen while learning to code, in my experience.

      1. Heh, yes. From a compiler error standpoint, the hardest ones to track down were always the typos or cases when I didn’t have enough close-parentheses. Figuring out why your code “works” (as in, it actually runs) but doesn’t do what you MEANT for it to do is another class of problem entirely and not one that can be solved by any degree of useful error messages, because the problem isn’t “you gave me bad info” but “you gave me good info, it just wasn’t the info you actually wanted”.

      2. ET says:

        “It compiles just fine on my machine!”
        “What compiler are you using?”
        “VS 200X. What are you using?”
        “VS 201Y…”

        1. NotDog says:

          It can get worse in the Unix world where any given code project I download also needs me to download a bunch of libraries, which themselves need a bunch of libraries, and everything needs their dependencies in a certain location, and to compile the damn thing I need to run several configuration tool and scripts.

          1. Isn’t it more or less the same for Windows? It’s just that the libraries are called “dll”s, and each application mostly rolls its own so you have a dozen probably-slightly-different versions of the same library, each of which may break in a slightly different way. But at least they’re automatically included.

            1. guy says:

              Except when they aren’t. Then the software gives you an error and may proceed to work perfectly anyway.

              It’s uncanny when that happens.

  6. Starkos says:

    Highlighting the errors in colored boxes would also help.

    1. Wilcroft says:

      Most GUIs or IDEs (Integrated Development Environments; stuff like Visual Studio or Eclipse) will highlight errors based on the compiler output.

  7. HeroOfHyla says:

    The worst is when the error simply isn’t your fault. I was trying to get SDL working on Windows last night, and one of the errors I was running into turned out to be a known bug with one of the header files included with SDL2.03, and I had to find a link on a stackexchange to download a replacement file.

    I still haven’t managed to get everything working. On one of my projects (the one I copied over from Linux) I finally managed to get everything to compile, but it crashes on launch. On another, Eclipse insists it can’t find any of the SDL files. I wind up looking at a bunch of angry red “could not be resolved” errors in the IDE, but it still builds without complaint.

    1. ET says:

      Good old upstream bugs! :S

  8. lethal_guitar says:

    Well, one of the reasons why C++ has especially terrible error reporting is that the language is hideously complex to parse. For one, there’s the preprocessor, which already complicates things (ever had fun with complex, nested, multi-line macros?). But the grammar itself is especially complicated. Whereas most programming languages feature context-free grammars, C++’s is undecidable (google “The most vexing parse” for an example). Not to mention that templates are Turing-complete..

    Due to all this, many modern languages already have quite pleasant error reporting in comparison to C++. I think this is what John was referring to in his talk: He wants the language he’s proposing to feature error reporting at least on the level of modern languages like Go etc., because everything that’s better than C++ will be “pleasant” in comparison.

  9. Hamilcar says:

    I am learning programming (so keep the programming posts coming, Shamus!) and have learned pretty quickly to ignore the error messages. I am amazed at how the compiler cannot just say, “Dude, you forget the end the line with a semi-colon!”. You would think, that errors in syntax and punctuation would be easy to point to. Oracle SQL is probably the best at this that I have seen, where it will often remind me that my statement is missing a keyword. But, other languages I have dealt with are clueless as to what went wrong. I guess, the reason is that the syntax and punctuation is there for a reason. Like grammar rules, if you ignore them, then you get a nonsensical statement or a sentence with a meaning different from your intention. So the compiler can’t just say “You forgot a comma.” because it is reading your statement as written rather what your intention was. The compiler is too literal and trying to compile your statement as written.

    1. Matt Downie says:

      Well, there’s no need to end a line in a semicolon in C++ – you can split a statement across multiple lines. Compilers are pretty much required to ignore line breaks.
      So what you’re wanting is a smart function that looks at what you’ve written and how you’ve formatted it, and then tests modifications such as adding a semicolon in likely places to see if that would fix the problem and then suggest a possible solution. Which is possible to do, but not something trivial.
      In the past I’ve seen ‘missing semicolon’ type error messages that were actually something else completely.

      1. Tim Keating says:

        Where he said “end a line”, I’m pretty sure he meant “end a statement,” since most statements are one-liners. And in C++ you *do* have to end a statement with a semicolon.

        1. Bloodsquirrel says:

          But the compiler doesn’t know when you intended to end your statement. It’s got a string of tokens that don’t add up to a valid statement. Is that because it’s two valid statements not properly separated? Or maybe it’s two invalid statements not properly separated. Or maybe it could be different sets of two valid statements depending on where it’s split.

          1. WJS says:

            Still, the compiler would basically be checking for three things:
            1: It encounters an unexpected symbol
            2: This symbol is the first (non-whitespace) thing on the line
            3: The current statement before this symbol is complete
            And it would just print “Did you forget a semicolon?” on a new line after the error. It has to do 1 and 3, or it wouldn’t be able to compile anything. Technically, it should be trivial to implement. The hard part would be collecting a list of “Common errors” and deciding which are common enough to check for, since you can’t predict everything that the user might have been trying to do.

  10. EwgB says:

    Interestingly enough, I’ve been programming in Delphi professionally for the past 5 to 6 years (yes, the language still exists and is actually being developed quite actively in recent years). And I have the feeling that the error messages in Delphi are much more helpful than those in C/C++ and Java. Part of it might be the phrasing issue you mentioned in the post, but part might be the fact that Delphi has a much more restrictive syntax than C family languages. For example every local variable used in a function must be declared in a specific block before the function body, for-loops can only increment or decrement by one (none of the fancy stuff like putting executed code in the for-loop header) and a lot of other things. This makes parsing Delphi easier and might also make error detection simpler, thus leading to more precise and helpful error messages.

    Full disclosure: I am in no way an expert in compilers and have only superficial knowledge of compiler construction.

    1. blue_painted says:

      The single parse compiler helps too – forcing the programmer to declare before use. This does mean you can find yourself facing “Circular unit dependency” more often than you’d like … but super-fast compiles and builds makes up for that!

  11. avwolf says:

    Another factor as to why the compiler can’t just say “hey, you can’t bitshift a float” is that C++ permits operator overloading. The compiler knows that the operator >> doesn’t let you have floats there, but it doesn’t know what operator >> might possibly mean. The *programmer* knows that, in this case, it means “bit shift right”. But what if you’re looking at I/O instead? Then it’s a stream operator and not a bitshift. How can the compiler tell the difference between the two? Even worse, what if it’s some custom operator on a custom class that doesn’t do I/O streaming *or* bitshifting.

    As mentioned by others, the compiler doesn’t have the semantic understanding of what the programmer means, it only has the syntactic understanding of what the programmer told it. Since (some) operators often have multiple meanings, it’s extremely difficult for the compiler to remark anything more than “the thing you said is wrong because I don’t know any way to use ‘>>’ with a float on both sides.” The programmer *must* understand the error (be it by reading the message or looking at the code) because the compiler *cannot*.

    1. DrMcCoy says:

      The day a compiler is able to give you useful error messages is the day it can write your program for you.

    2. If the compiler *can’t tell* the difference between the two, then how can it compile the code into an executable in the first place? It has to “know” what the operator “means” in order to compile the code.

      But it doesn’t HAVE to translate it for you, it could simply say “Cannot >> this variable”. All of that info is definitely accessible. It’s not HUGELY informative, but at least it’s telling you where the problem is located.

      1. Zukhramm says:

        But that’s already what it’s saying, although perhaps formulated in a less readable way.

        1. 4th Dimension says:

          And that is the exact problem. The way error messages are expressed, as if they were written for some system where there was a limit on message length, and knowing Cs age it probably was.

          1. Zukhramm says:

            It seems it’s written with the focus on where the actual error occurs (the arguments), but it’d probably be easier to quickly understand if it focused on the operator, since you kind of automatically check the arguments when you go to check the operator anyway.

      2. guy says:

        It can only tell what the operator means when it’s got valid operands. Specifically, it knows what int >> int means, and it knows what String >> String means. It also knows that float >> float doesn’t mean anything.

        1. WJS says:

          It would probably help if it told you that.

          Operator “>>” can mean:
          int bitshift int
          Stream extract Stream

          Or whatever. This would require anyone overloading an operator to give it a name, however, so it might not be applicable to existing code. You could do

          Operator “>>” can mean:
          int >> int
          Stream >> Stream

          however.

      3. fizmat says:

        Because compiler chooses the correct overloaded operator based on parameter types. So when the types are correct there’s no problem. When you try to use >> with floats and have no overloaded << operator for floats, it can't tell which one of the other <> is basically a name of a function

        “You cannot >> this variable” does not work. What if both operands are variables? What if both are expressions? Why can’t you >> this variable, because of its type or its value? The original error is verbose, but it tells you exactly what the compiler did not like and works robustly. It also works for any operator, regardless if you can verb it or not.

        The only way to _correctly_ display a more “human” error is to have some system to look for context (Aha, the left operand. Is it a variable? We should call it a variable in the message then.) And somehow combine this context into a message, which would require some understanding of human language. This is hard and prone to errors, which you definitely don’t want in your error-reporting code.

        1. Veylon says:

          It could “guess”. There have got to be a hundred or so very common programming errors in any given language and mixing up >> with > must surely be one of the C++ ones.

          So the compiler can hit the error, check it’s dictionary of folly, test > instead of >>, see if it compiles that way, and then ask “Did you mean ‘Speed > 8.0f’?” on the next line past the error description if it did.

          1. WJS says:

            The trouble with that is that forgetting to convert a float to an int is also a common error. You’d have to suggest “Speed > floatToInt(8.0f)” as well, and the kind of rookie programmer who wouldn’t immediately realise that they meant > rather than >> might not realise that > can work on floats.
            I think this was a bad example of a complicated compiler error, really, because it’s a really easy one. The first thing in the message is the bad operator quoted. I don’t even work in C and I would get that straight away.

  12. Chris Davies says:

    You say that, but we know from long experience that any software that tries to make semantic deductions about what it thinks you meant is utterly infuriating.

    “It seems like you’re writing a letter.”

    Compiler error messages are clear and unambiguous, and not even the novice programmer has much difficulty translating them in to the fix for their mistake. Perhaps a better optimisation for compilers would be to print the errors in reverse order, that at least would save time.

    1. ET says:

      I’d like a setting to just spit out the line numbers with errors, instead of messages. Would make it a lot easier to read for people who have learned to ignore everything else. :D

    2. Exasperation says:

      I had a CS prof who had an interesting story about that, actually. The story goes that, as originally designed, the assistant was useful and not intrusive. It would basically watch the activity of the user for signs that they were having trouble (for example, mousing through the dropdown menus one after the other but not selecting anything), and only show up if the user activity indicated it was necessary. Then the engineers who designed it showed it to marketing. Marketing basically said “Wow, this is really great, but it doesn’t show up very often, so most people aren’t going to be able to see what a wonderful tool you’ve made. You need to turn the sensitivity ALL THE WAY UP so that people will be constantly reminded of what you’ve made.” And thus, a useful tool was turned into a PR disaster.

  13. mhoff12358 says:

    One time, I got an error message from the compiler alerting me that there was a problem, but it had no idea what it was. The error message has the actual text “Unknown error, giving up”.
    No line numbers or anything, just unknown error.

    1. I’ve gotten those before. Usually they were a result of a missing ).

    2. Zukhramm says:

      I can’t remember exactly what it said but I do remember valgrind getting snarky with me. Something like “too much going wrong, please fix your code”.

  14. kerin says:

    Clang has sumptuous error messages – when I switched away from GCC, I almost cried. Errors are always provided with context, and color highlighting. Error text is almost always in plain English.

    Switching to Clang was like going on vacation, and knowing I never had to go back.

    1. Blake says:

      Agreed. Especially for templates.
      For example, I have a function “TryGet” that takes 2 arguments, the second of which is templated on a type. If I add a third argument then my Win32 platform gives me:

      {File&Line}: error C2782: ‘bool CLS::TryGet(const char *,T &,const T &) const’ : template parameter ‘T’ is ambiguous
      {CLS header}: see declaration of ‘CLS::TryGet’
      could be ‘const char [1]’
      or ‘{type}’
      File&Line}: error C2780: ‘bool CLS::TryGet(const char *,T &) const’ : expects 2 arguments – 3 provided
      {CLS header} : see declaration of ‘paRuleDict::TryGet’

      The platform that uses Clang gives me:

      {File&Line}: error : no matching member function for call to ‘TryGet’
      {CLS header}: note: candidate template ignored: deduced conflicting types for parameter ‘T’ (‘{type}’ vs. ‘char [1]’)
      {CLS header}: note: candidate function template not viable: requires 2 arguments, but 3 were provided

      Which is much nicer to read.

      As for Shamus’ example, Clang gives:
      error : invalid operands to binary expression (‘float’ and ‘float’)
      Which is nicer than gcc, but could still be improved by following it up with:
      “You used operator >> did you mean to use operator > ?”

      1. Bryan says:

        The most useful part of Clang’s error messages, in my experience, are where it provides the common short names instead of full template expansions. So when you get a template type slightly wrong, because the function you’re calling wants some type with a reference down at the bottom layer and you gave it a pointer instead, or whatever, it’ll give something closer to what you actually write in the program.

        g++ will do a full template expansion including all the default template args. Clang will do that too, but will also say something like “(aka std::unordered_map<std::string, std::vector<struct Foo*>>)”. Which is far easier to scan against the mismatched type’s short name to find the difference.

      2. MadTinkerer says:

        You look like you want to use the > operator. Would you like help using the > operator?

  15. Svick says:

    you could even have errors with optional expanded explanations that link to the language's wiki

    It kind of already does that. If you google the error number (like C2297), you’ll find an MSDN page explaining the error in more detail, including examples.

    That being said, if you don’t know those pages exist, you probably wouldn’t have a reason to google the error number.

    Also, in this specific case, the page is not very helpful (because the error is not specific to bit shifts or floats).

  16. droid says:

    The lvvm compiler has better error messages as one of its key features.

    Edit: ninja’d by kerin, clang and lvvm are related.

  17. nm says:

    This problem is worse for C++ than for most languages I’ve used. However, Clang is purported to do a terrific job of emitting sensible error messages. The statement that compilers are bad at giving us useful error messages is, in general, a false one. Most compilers I’ve used are wonderfully helpful for most of those things, and I’ve even used some that try to find a small change that would make your code compile.

  18. Retsam says:

    Not to turn this into a programming language holy war; but I do think C++ might be the worst commonly-used language for error messages. The fact that Java has a much more restrictive idea of what operations are permitted allows for much better error reporting. The above example would yield:

    java: bad operand types for binary operator ‘>>’
       first type: int
       second type: float

    But, also (which I’m surprised didn’t get mentioned in the article itself), is the case where you aren’t applying floats to the bitshift, i.e. “if(speed >> 8)”. In C++, this is going to pass compilation, but is going to be a bug (speed will always be 8 or 0) but in Java, you’ll get “Incompatible types, required: boolean, found: int”, which again, I think is a pretty clear error message.

    1. nm says:

      Implicit cast to bool is one of my least favorite things about the C family of languages. Integers are not the same as booleans!

      1. Zukhramm says:

        In C it least, it’s not so much an implicit cast but more that there aren’t really any booleans at all.

      2. ET says:

        I hate implicit casting, period. The benefits of saving a couple of characters not typing (NEW_TYPE) in front of your value don’t outweigh the penalties of unwanted casting.

    2. Athan says:

      There’s more than one C++ compiler. Munging the example a little to compile under g++ (v4.7.2 from Debian) I get:

      float.cpp: In function “˜int main(int, char**)':
      float.cpp:5:15: error: invalid operands of types “˜float' and “˜float' to binary “˜operator>>'

      1. Shamus says:

        I like that a lot better! In my perfect world (and ignoring the problem of operator reuse / overloading) I’d have it say “bitwise” in the error, but that’s still much better than the error I got.

        1. Liam O'Hagan says:

          C# is a bit nicer;

          Operator ‘>>’ cannot be applied to operands of type ‘float’ and ‘float’

          1. Daemian Lucifer says:

            Indeed,c# is nice in most cases.But god help you if you forget the () behind some commands.

            1. 4th Dimension says:

              Well you have to add () after methods. If you don’t do it you will be calling a property. It’s perfectly fine. On top of it all you are unlikely to forget since you will be working in VS and it has excellent intelisense.

            2. Liam O'Hagan says:

              There’s also a lovely performance gotcha is you accidentally use the count() method on some collections instead of the count property.

        2. Matt Tucker says:

          How would it possibly know to say “bitwise” when “float >> float” isn’t defined, and the >> operator is only a bitwise shift when it’s an infix operator of two fixed-point numbers?

          Does “binary” in this context really mean “operates on binary values” or does it just mean “affects two operands”?

          1. Zukhramm says:

            It could know to say that if it wasn’t possible to use it for anything else.

            And yes, number of arguments. Which is why people sometimes call ? “the ternary operator” when it’s really a ternary operator, albeit the only one in C.

          2. Endymion says:

            Its a binary operator because of its use of two operands. Similarly, ++ and — are unary operators, and the ?: thingy is the trinary operator.

            And yes, the problem with giving it the label bitwise is that <> can really be used for anything if you don’t mind making your code confusing. Then again, that same logic applies to +,-,=,==,>,<,++,–….. well, basically all the operators can be overloaded to mean whatever. Not sure if ?= can be though. Now I'm curious.

            1. silver Harloe says:

              http://en.cppreference.com/w/cpp/language/operators

              Restrictions
              * The operators :: (scope resolution), . (member access), .* (member access through pointer to member), and ?: (ternary conditional) cannot be overloaded
              * New operators such as **, <>, or &| cannot be created
              * The overloads of operators &&, ||, and , (comma) lose their special properties: short-circuit evaluation and sequencing.

        3. Phill says:

          It can’t really say bitwise operator since as far as intrinisic operators go it can be both a bit shift right or a stream extraction operator (iostream >> variable – to read data from a stream into a variable).

          Plus being c++, the user can the proceed to define the operator>> for their own classes to do whatever the hell they like (although sane programming practice would rather discourage you to do more stupid things like designing a class that is a simple wrapper for a float, and then defining the >> operator to perform exponentiation).

          This is a problem with c++ operator definitions. The compiler simply can’t stick in some string to say what it thinks the >> operator represents without certainly getting it wrong in some cases, and end up being even more confusing. The only approach guaranteed to be valid is to report which operator it can’t find an operand match for, which is what it does.

          Could it be formatted better to present the information better? Sure, see some of the other examples.

        4. kdansky says:

          clang also has “better error messages” written down as one of its primary objectives. It’s just VC++ which is unbelievably annoying with its error messages. You haven’t even talked about linker issues, where you don’t get line numbers, and sometimes not even file names.

  19. Sabrdance (MatthewH) says:

    It’s exam season, so I’m grading lots of essays -not programing, I grant you, but still dealing with errors in the language.

    As part of my quixotic quest to improve writing, I grade the exams for style and grammar. Usually I will try to correct the bad sentence to say what I think the student was trying to say and then explain the correction. This can be quite hard when students are using a word that is technically correct but doesn’t carry quite the proper meaning, or when the meaning of the sentence will change based on punctuation and it isn’t clear that this comma was intended.

    For the worst sentences, though, sometimes all I can do is highlight the point in the sentence where it goes wrong and say “the sentence makes no sense beyond this point.”

    I speak English as my native language. I can’t imagine how difficult it would be for a computer to try to parse a programing language written badly enough.

    1. Daemian Lucifer says:

      Out of all the people here,I think you hate me the most.Im sorry.

  20. Steve C says:

    What there needs to be a cute animated character in the corner of the screen offering advice. Maybe a paperclip with eyes. It would use heuristics to figure out what you are trying to do and… wait a min there appears to be a mob at my window with torches and _____

    1. DIN aDN says:

      * Flashlights?

      * Batteries?

      * Marshmallows?

      * Click here for more options

  21. MichaelG says:

    My compiler construction professor just said “generating good error messages is hopeless. Maybe you can get it to at least point to the first piece of code that’s wrong. Then just say “duh?” and quit generating errors, because the programmer won’t look any farther.”

    1. Daemian Lucifer says:

      You know,that would be preferable to some nonsense Ive seen.Because the way it is,a simple mistyped character can change the whole line to mean something else,and then the error will be for something completely unrelated.Just saying “duh?” would at least not point in the wrong direction to solving that mess.

      1. Paul Spooner says:

        Agreed on all points. Thought I would replace “duh?” with “lolwut?”
        In any case, this approach would take a lot less effort to maintain.

  22. Norman Ramsey says:

    I used to write compilers for a living (so you can safely assume that I know how to decode the error messages). Rule One: no matter what the language or the compiler, always, always, always have your computer just take you to the location of the error. Actually reading the message is a last resort.

    For those of you doing C or C++, I’ve been pleasantly surprised by the error messages from clang.

  23. MadTinkerer says:

    “Having said all this, I'll admit it's a tough problem to solve.”

    Actually, it’s a computationally impossible problem to solve. Computers are incapable of correctly guessing human intention. This is because they are designed to always follow instructions perfectly literally, and human intention involves intuition, which is unquantifiable.

    If anyone reading this thinks I’m full of it, I can demonstrate the correctness of the above paragraph with just one word: Clippy.

    The silver lining to this unsolvable problem is that you can instead try to create a set of all possible syntactically correct couplets involving each element on the line of code and have the computer guess at the most likely thing that you meant in the manner of a very well implemented spellcheck. Which would be better than what we have.

    But the correct guessing of human intention (regarding non-specific subjects (because if the subjects were sufficiently specific in the first place there would be no error))… just isn’t possible because human intention is not quantifiable.

    1. Tim Keating says:

      It’s also impossible for humans to run a mile in under four minutes.

      1. Phill says:

        Different sort of problem ;)

        (It’s currently impossible for a compiler to run a mile in under four minutes however).

        The thing is that even if some future computer gets to be as good as inferring intentions as a human, it still won’t be good enough. Anyone who had spent much time in a programming team will probably have come across code that is clearly wrong but couldn’t say for certain what the intention of the person who wrote the code was.

        Either because the code is so opaque as to be unreadable (bad practice) or because, more likely, there are several plausible things that the coder could have been trying to accomplish and there isn’t enough information to reliably say which one is the right one.

        I’m in the camp that thinks that the compiler trying to guess what you meant and give helpful error messages base on that will work fine 95% of the time and be misleadingly awful 5% of the time.

        Ideally you get the ‘raw’ error message and also the compiler’s best guess which you can then ignore in those 5% of cases where you have no idea what it is on about.

      2. MadTinkerer says:

        No, but really, if you look up Turing’s writings, at some point he proved that computers can do everything that’s calculable, but not things that are incalculable. Something needs to be quantified before it can be calculated or computed.

        So the question is: what are you going to want? Five minutes from now? An hour into the future? How about this time tomorrow? Write down those times and guesses, set a couple alarms and tell me how accurate your guesses were. Then give me an algorithm that perfectly predicts your desires from now until your death. Because that’s what the computer needs to know in order to precisely guess your intentions.

        That’s why it’s impossible.

        1. Ayegill says:

          Computers obviously can’t do things that aren’t well defined. That doesn’t even make sense, computers are themselves well-defined machines(well, in theory anyway), how could they possibly solve a problem that’s not well defined? What does that even mean(rigorously)? That’s not what Turing’s work was about.

          What Turing showed(among other things) was that there exist problems which A) are well-defined, and B) can’t be solved by computers.

  24. Exetera says:

    I don't know who composes error messages now, but I'm willing to bet that:
    1. They know the language very, very well. So well that really complex stuff can seem trivially “obvious” to them.
    2. They are an engineer, and were chosen for their technical prowess, not for their communications skills.

    My two cents go towards “because the error messages were written by the parser guy, and were designed to make sense to the parser rather than to whatever meatbag might be operating it.”

    (Also, nitpick, Jonathan Blow’s name doesn’t have an “h” in it and shouldn’t be abbreviated “John.” It is correctly shortened to “Jon.”)

  25. DaMage says:

    segmentation fault.

    1. NotDog says:

      Bus error.

      1. Those bastards are always going by without stopping when they’re not really all that full, just because the driver can’t be bothered to tell people to move to the back.

  26. silver Harloe says:

    Let us not let the perfect be the enemy of the good.

    Just because it’s computationally impossible to always generate the right error message, doesn’t mean we can’t find low-hanging fruit and fix it.

    Like anytime you’re tempted to include a << in an error message, just make sure to also output "did you mean < ?" and the word "bitwise" in there somewhere. Much better for not much work at all, and no fancy intelligence needed.

    1. Zukhramm says:

      I’m not sure that’s something that should be in errors, isn’t that what warnings are for?

      1. silver Harloe says:

        I’m talking about “starting with Shamus’ example: IF the compiler has already decided to print an error involving the text ‘>>’, THEN also make sure the message includes XYZ” – I’m thinking that there’s a ton of low-hanging fruit to be snagged with very very very simple enhancements if we give up trying to be smarter about error detection until a future time.

        Heck, what I’m envisioning right now could be done with a simple script that you pipe your compiler output to:

        while ( line = readline ) {
        print line;
        if ( line contains ‘>>’ or line contains ‘<<' ) {
        print "Shamus just wanted me to say 'bitwise' here";
        }
        // else if () … etc
        }

        though, of course, it would be faster to bake it into the compiler

        1. Zukhramm says:

          I mean that too, just that I think that sort of thing shouldn’t really be part of the error.

          So, I think it should say something like:

          “Error: line n: Cannot use operator ‘>>’ with arguments float and float
          Warning: line n: Invalid use of operator ‘>>’, did you mean ‘>’?”

          1. silver Harloe says:

            Ah, that’s where I disagree.
            In my mind, the same bit of code should generate ONE of
            1) an error
            2) warning + code that runs under the ‘dangerous’ interpretation
            3) code

            IMHO (? or is it just my opinion?), a warning isn’t defined as “just some text I felt like saying here.” It is defined as “I compiled that into valid code, but this looks like a common mistake, are you SURE?”

            having it generate both an error AND a warning makes me think “which is it, compiler? valid code or an error? make up your mind!”

            so your example:
            Error: line n: Cannot use operator ‘>>’ with arguments float and float
            Warning: line n: Invalid use of operator ‘>>’, did you mean ‘>’?

            to me should output:

            Error: line n: Cannot use operator ‘>>'(bitwise shift right) with arguments ‘speed'(float) and ‘8.0f'(float), did you mean ‘>’?

            Because the ‘warning’ is really *part of* the error.

            However, given *actual* compiler output is:

            error C2297: ‘>>’ : illegal, right operand has type ‘float’
            error C2296: ‘>>’ : illegal, left operand has type ‘float’

            I think we could drastically improve that without even rebuilding the compiler by using a filter script on the compiler output that changes the result to:

            error C2297: ‘>>’ : illegal, right operand has type ‘float’
            …. Problem might be using bitwise shift instead of > ?
            error C2296: ‘>>’ : illegal, left operand has type ‘float’
            …. Problem might be using bitwise shift instead of > ?

            (note: of course, if you really want, you could change the 4 spaces at the front of the wrapping script’s output with the word ‘warning’, I just think, for reasons explained above, that having a line be both an error and a warning is confusing)

            Moreover: I’m suggesting this because while it’s all well and good to talk about making a new language or a new compiler to improve our lives – those are big projects and we could make progress faster with something like a filter script that gives helpful suggestions based on the compiler output. It wouldn’t be perfect, but back to my original point: we shouldn’t let the perfect be the enemy of the good. It would take 5 minutes to write the first version of this script, and it would be fast to add new advisories to it as they come up in the future, so that 3 years from now you might have added a whole library of extra knowledge into the script and made it really helpful for common errors. The only issue I can see is that Visual Studio might not let you pipe the compiler output into a script automagically.
            I know I could do this easily in Linux ( 2>&1 | script ), but as noted elsewhere in these replies, g++ already makes better error messages than MSC++, so it would be pointless :)

            1. Zukhramm says:

              They way I see it, errors should only contain that which is an actual error.

              Also, bitshifts are valid aas conditions but the suggestion that you might have still meant less/larger than is probably still useful, even if the arguments happen to evaluates to integers.

              Actually, it’s probably more useful since that won’t cause an error.

  27. Toastgoblin says:

    I disagree with quite a few people here, because I think the message isn't remotely helpful enough and that a slightly different tersely-worded message isn't a big improvement. In particular, “cannot >> this variable, illegal type” (one suggestion) isn't particularly helpful, because you still don't know:
    * what operation the computer might be trying to perform
    * what type the variable is right now
    * why the variable thinks it is that type
    Things like doubled operators seem obvious, but it's so easy to just blank on that stuff and get lost wondering if there's some strange rule where values greater than 9.4 produce an error message because of a weird implementation.

    Ideally, I would like to see messages that give as much information as possible.

    Error C2297 in line 4, column 5-14.
    Attempted operation: bit-shift on subject speed, amount 8.0f
    This failed because: bit-shift does not allow a float-type variable as amount; 8.0f is a float as defined in line 4, column 14-17.
    This also failed because: bit-shift does not allow a float variable as subject; speed is a float as defined in line 1, column 1-11.

    If a language assigns types that aren't specified, it should point this out too. An even nicer version would make it possible to track things right back through multiple functions, so that if speed takes the result of a function that was passed from yet another function before we hit this line, you could still trace it back to the lines that defined the type of both speed and whatever it started out as.

    I've had countless problems because of variable type issues, where error messages didn't make it clear that this was the problem and where it was nigh-impossible to track down where exactly the program was defining the required type and the actual type. Admittedly, this is mostly in Python in cases where I was passing variables between functions, and between assumed default types, and operations requiring different types and occasionally just converting them… it wasn't pretty.

    If the language allows multiple possible operations, it could simply list all the things it tried and why they didn't work. In any case, “I don't know any operations to perform that use this set of variables with these types. They are here and this is where they were defined” would still be a vast improvement on any language I've seen.

    With things like missing line-end characters, I feel like a “helpful suggestions” might be nice. “I couldn't continue past line 15. There is no semicolon at the end of line 14. Did you mean to do that? If not, click here to add one. Otherwise, click there for more suggestions.”

  28. Kingmob says:

    I’m afraid that the day the compiler understands what you meant instead of what you wrote, is the day the compiler no longer needs you to write the program. That is not to say error messages can be improved, but I think that it is inherent to the concept of a compiler that it has to be very ‘literal’.

  29. Neko says:

    I find the most entertaining error messages are those caused by a mismatched quote mark. As far as the compiler understands it: one minute you’re declaring a string literal, then the compiler closes its eyes for a moment, then BAM! we’re 14 lines further down and why the hell are you attempting to bar a baz with a quux?

  30. clang++ and g++ have been working on better error messages for C++ for a long time, and it’s paying off. Latest versions of those compilers will show better context and sometimes even know exactly what the fix is.

    LLVM’s clang++ will output:
    error: invalid operands to binary expression
    . . . ('float' and 'float')
    . . . . if (a >> 8.0f) {
    . . . . . . ~ ^ ~~~~

    GNU’s g++ will output:
    error: invalid operands of types "˜float' and "˜float' to binary "˜operator>>'
    . if (a >> 8.0f) {
    . . . . . . ^

    Hrmph, code tags don’t preserve spaces…add CSS preformatted to them?

  31. Tim Keating says:

    I am NOT a compiler writer, but from what I understand about parsing, I believe the problem is that the compiler is walking the AST (which should be a DAG AFAIK) while carrying around a current state. At the leaf node where the error can be detected, the compiler doesn’t know enough about how it got to the current state to explain it to you. The code that evaluates the AST node knows NOTHING about walking the graph… and rightfully so.

    1. silver Harloe says:

      “The code that evaluates the AST node knows NOTHING about walking the graph… and rightfully so.”

      in 1990.
      in 2014 we can spare some extra bytes to keep enough debug info in memory to write a decent message when we bump into a problem. … which is why so many modern compilers *do just that* (see numerous examples previously posted in this thread). MSC++ is the problem here more than “compilers”.

  32. Phantos says:

    Confusing, vague error messages are bad enough.

    It’s especially frustrating when the error message is in a completely different language for seemingly no reason.

    There was a free-to-play game about cartoon tanks that, when it failed to load up, would say something along the lines of :”Website game id no Jim Breuer”.

    Even though everything else about it was translated adequately into more than one language. That seems like one of the more important places to not skimp on the localization.

    1. Exasperation says:

      I once ran across a game created for a programming class that crashed with an “Y tu madre tambien” error. IIRC, it was actually a problem initializing graphics or some such.

  33. Ales in the comments had a pretty good solution, it could spit back “Are you really trying to bitshift a float?”
    That should make most folks turn on the light.

    Though in a new language this stuff can be avoided y simply doing

    “gt” for Greater Than and “gte” for greater than or equal.
    “lt” for Less Than and “lte” for less than or equal.
    “eq” for equal.

    In many languages gt is > and gte is >= and equal is == or ===- and a single = to set a variable value.
    Some languages for example allow you to use just = to both set and compare and instead keeps track of it’s context. (PureBasic does this).

    1. Zukhramm says:

      You avoid one problem but instead make it harder to read.

      1. First off I meant to type Alex not Ales (oops), and === rather than ===-.

        Secondly, not sure if it would be harder.

        IF variable > 1

        versus

        IF variable GT 1

        Most use syntax highlighting text editors or IDEs these days,

        Also the use of GT and similar is often used in assembler and it’s not that hard to read that really. (not exactly GT, in asm there is a Jump If Equal or Greater which is JGE in Masm if I recall correctly)

        Also harder to read is what I’d call stuff like === or !==.
        In PHP or Javascript it’s particularly nasty to do a = when you meant == for example, instead of comparing you end up setting a value and depending on the context you may not notice the error until you have ripped your code apart again.

        I’m also not keen ong languages that let you do stuff like
        c = 1
        without having previously defined it, if you are required to predefine stuff then you may catch errors where that c = 1 should have been c1 = 1 for example.

        A lot of the syntax stuff has been added to save time or because coders are lazy (otherwise we would’t try to write the shortest possible piece of code for something).

        In my eyes typing an extra character or two here and there if it means less bugs and issues with bug hunting or annoyances like that then I’d consider it worth it.

        1. WJS says:

          I’m pretty sure there is a reason that pretty much all modern languages have converged on operators being non-alphabet characters. I don’t care what colour your editor paints them, special characters are always going to stand out better than random blobs of alphabet characters. Making it ambiguous whether a string of letters is a variable, a function, or an operator is going to be more confusing, not less. And do we really need more reserved words we can’t use for variable names?

  34. Bropocalypse says:

    There’s a potential compromise here. Have it show the technical version of the error, then in the same message, attempt a layspeak interpretation of what’s going on.

  35. Mrcl Pfffr says:

    I love the D programming language but in this context dmd is even worse:

    $ dmd error.d
    error.d(3): Error: ‘speed’ is not of integral type, it is a float
    error.d(3): Error: ‘8.00000’ is not of integral type, it is a float

  36. HeroOfHyla says:

    For fun, here’s a 196 line error message that g++ spat at me:
    http://pastebin.com/fPhMcz11

    The cause? A missing pair of () after a method call.

    1. WJS says:

      Wow. It tells you the error in the first four lines, and then goes on to ramble for nearly 200 more.

  37. Anachronist says:

    I thought the ‘right operand’ message example in this article was clear enough, especially because it started out by showing you the problematic operator.

    What’s worse, to me, is the links to ‘helpful’ web pages that explain the error message in greater detail. When the IDE shows me a cryptic error message and I click on the link, my browser comes forward to show me a Microsoft page that utterly fails to enlighten me about what might be wrong in my code.

    Some compilers are better than others in this regard. The GNU C++ compiler for Unix systems can be (if you want it to) quite verbose and specific about what it doesn’t like about your code.

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun. Your email address will not be published. Required fields are marked*

You can enclose spoilers in <strike> tags like so:
<strike>Darth Vader is Luke's father!</strike>

You can make things italics like this:
Can you imagine having Darth Vader as your <i>father</i>?

You can make things bold like this:
I'm <b>very</b> glad Darth Vader isn't my father.

You can make links like this:
I'm reading about <a href="http://en.wikipedia.org/wiki/Darth_Vader">Darth Vader</a> on Wikipedia!

You can quote someone like this:
Darth Vader said <blockquote>Luke, I am your father.</blockquote>

Leave a Reply

Your email address will not be published. Required fields are marked *