Shoot-out: most annoying compiler error message

Today, I ran into a compiler error message which was hopelessly uninformative. Since I am up for something light-hearted, I thought I might as well just ask if anyone remembers his most annoying compiler message. I guess anything goes, well maybe except for the "e345: internal error message" kind of type.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Visual Basic

VB6 sometimes produces the error "Undefined Type", displayed in a message box without providing any context whatsoever (no name for the offending type and no location, not even the name of the source file - it could be anywhere in the project).
As a response you get to click "Ok" and the compilation aborts.

Disclaimer: I don't use VB6 out of personal choice ...

Run-time error '429'

ActiveX can't create object.

But which object, VB?

+1 on that, I used to hate that one.

"Error: not yet implemented"

Thanks, g++!

Notable: GHC's "Expression has type a, expected type a"

Ad majorem dei gloriam

Does that GHC error arise because there are two a's in different scopes?

Excusables

Yes, I believe so; both of the messages I listed are (IMHO) completely fair for a compiler to complain about.

Who's da man?

The scopes problem is a genuine issue, I think. There are ways to denote variables in different scopes (for example, via paths in the source, although that is for value variables not type variables), but that would complicate the message even more. Personally, I think compilers should produce precise and unambiguous messages which are not necessarily in human-readable form; then you can have one external program which processes them and makes it human-readable. That way if, for example, your compiler is being run under an IDE, the IDE could process the information and, in this case, would be able to highlight the two distinct sources of the a's.

Text at least

I think that error can only appear when explicit annotations force the names of both type variables to "a", so in this case there should be text locations to report for type variables as well.

"Expression has type a, expected type a"

I got one of those from Eclipse the other day while writing Java.

The method addAll(Collection<? extends Matrix>) in the type Collection<Matrix> is not applicable for the arguments (Collection<Matrix>)

The real problem turned out to be that there were two classes in different packages, both named "Matrix", and I had imported the wrong one, so that what it really meant was:

The method addAll(Collection<? extends foo.Matrix>) in the type Collection<foo.Matrix> is not applicable for the arguments (Collection<bar.Matrix>)

But it took me quite a while to stop cursing and figure it out.

Error messages which make you go umph!

... would have been a better title.

Anywayz, here's my own small (ocaml) pearl:

This kind of expression is not allowed as right-hand side of `let rec'.

Fortunately, these days we can google for quick fixes.

From an Overworked Student

Overheard from an overworked student in a C++ course:

Microsoft VC++: Ambigious Error
Student: Oh, I'm ambigious?!!

Least helpful explanation of an error

Way back in the old days, when I was in junior high school, I entertained myself by learning C with my trusty second-hand copy of Turbo C++ 1.0. I hadn't grasped yet that a switch statement could only switch on something of integer value, and so tried something of the following seemingly reasonable (at the time) form:

switch(someString)
{
case "someValue":
{
/* Do something */
break;
}

case "someOtherValue":
{
/* Do something else */
break;
}

default:
{
/* Complain */
break;
}
}

Anyway, what I got out of the compiler was "Non-integral switch expression." Not being immediately able to decode the meaning of this error, I decided to look it up in the manual. Borland's crystal clear explanation of the matter: "The switch expression you have attempted to use is not integral."

Or lack of message?

My greatest moment of aggravation with a compiler was actually due to the absence of an error message.

The C++ standard says "no length limits on names". Borland C++ 3.0 said "the length limit is 255 characters", which was pretty reasonable. But, in fact, the Borland linker had an undocumented limit of 63 characters--and, of course, this was on the munged name. So it was relatively easy (especially if you were using long names and/or nested classes) to hit the 63-character limit.

Now, if the compiler had thrown up an error message when it hit this limit, that would have been OK--a minor irritation, but usually a pretty easy one to work around.

It didn't. It just truncated the munged name to 63 characters.

Now, that's bad enough; but, in practice, the first 63 characters were often unique, so it could have worked. The problem was that, when the compiler called a function with a truncated name, it didn't pass any parameters on the stack.

Mind you, there was no reciprocal bug in the code generation for the function with a truncated name; it was still trying to read the parameters off the stack. If one of these parameters (say, the implicit this) was a pointer, the function then went on to trash memory. Since this was on Windows 3.1, this almost always meant at least a reboot, sometimes a reinstall.

It took me quite a while to figure out what was going on; I wound up having to inspect the generated assembly code. I submitted a bug to Borland, but, oddly enough, I never heard back. ;-)

PL-6 had "interesting" error messages

PL-6, the system programming language of the old Honeywell CP-6 Operating System had a most useful message that would occur from time to time:

"Error found between beginning and end of file."

Fortunately, once you found someone who knew what was wrong, it was fairly easy to fix. But the first time you saw this you weren't too pleased. You usually went chopping code out until you found the offending area and then deduced what was wrong. [BTW, it was an incorrectly called macro without a trailing semicolon, most times]

And, no, the manual was of no use. It just said that your code had errors.

PL-6 had temporal messages too!

As one of the developers of the Honeywell CP-6 system and PL-6 compiler, there were other good messages. I very much remember one I wrote that seemed good during coding and reviews. We were optimizing the PL-6 compiler and I had added some value range checks. The best description is a simple example, this is pseudo-code I do not remember PL-6 syntax.

define X integer range 0-1000;
define Y integer range 500-1000;
read X;
read Y;
X = X - Y;
if (X > 500) then
   msg("Sorry, X too large");
endif;

Now the compiler was smart enough to recognize that the minimum value of Y could be 500 and the maximum of X was 1000 so X - Y must be less than 500. When the compiler saw the IF logic it knew that block of code could be removed and did. But if you wanted to know all the optimizations performed by the compiler, the message said something like this:
'At this time', the condition can not be met, optimization will remove this block of code.

The message was properly placed with the IF block.

The problem is that many programmers did not understand (and yes the message may have been obtuse). The common joke was "well, if we compile again at a later time would the code then be included?"

Sorry, I think this qualifies as both a really geek joke and a poorly constructed message.

I recall PL/I having a

I recall PL/I having a message to the effect that while the code was correct the combination of features was unimplemented "at this time". I am not sure I remember correctly, but I think it was related to the insane iSUB feature of the languages.

right out of Bert & I....

I seem to remember an error message, and I'm not sure whether it was on a DPS-8/70 or a DPS-90, but it was something like "you can't get here"

Oz: conditional failed


{Show {fun {$ X X} foo end bar baz}}

The Oz Emulator says:

%**** Error: conditional failed *****************
%**
%** Missing else clause
%**
%** Matching: baz

Common Oz error message

Unfortunately, error messages like that are rather common in Oz, and they are often hard to comprehend. Here is another example.

{Map x Show}


%******************** Error: conditional failed *****************
%**
%** Missing else clause
%**
%** Matching: x

You typically get it whenever pattern matching comes across some value it cannot match.

case x of nil then nil end

Not a compiler but...

As VB and ActiveX were already mentioned, and parsers in fact are pretty close in spirit to compilers' lexers...

org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.

Cause unidentified, the problem disappeared without changing the input file.

Familiar

I've actually seen that often enough to remember what it actually means. It means some whitespace has been inadvertently put in front of the XML prolog. Possibly your IDE "fixed" the file between runs, without you noticing it?

More amusing than annoying, but...

CMUCL once gave me an error something like

Error: 42 is not a number.

This was due to a type-inferencing bug incorrectly deciding that a variable could never be bound to a number at a certain point and that a runtime type-error should be signalled without checking the value.

A Ken Thompson horror

Ken Thompson is known for parsimonious error messages. (The ubiquitous "?" from ed is [in]famous.) He mentioned a (FORTRAN?) compiler once (mercifully never released) that produced only two syntax error messages: JIM and JOE, for "Junk In Middle" and "Junk Off End".

Was "?" actually bad? I've

Was "?" actually bad? I've never actually used an ASR-33 at 110 baud, but I imagine you have, and it seems like "?\n" might be a more pleasant error message in that environment than "Invalid address", which would take two or three seconds to print, let alone "%EDITOR-E-EOF, the address specified is past the end of the currently open file".

APL

APL\360 occasionally produced "nonce error", which was its abstruse way of saying that what you typed was legal, but the implementation wasn't capable of handling it. If you've seen Duff's Device you might understand why I know this.

Duff's Device

Duff? The Duff?? Awesome! As an assembly programmer, that was the C hack that I found that convinced me that C was an OK language... :-) What are you doing these days?

PKE.

Current whereabouts

My condolences...

Unlike many online fora, LTU isn't really an online sewing circle, so this is probably offtopic. Nevertheless, shortly after birthing the Device at the Lucasfilm computer division (the future Pixar) I moved to Bell Labs CS Research in New Jersey for 12 years, where I continued doing research in computer graphics and worked on Plan 9 and infrared wireless networking. In 1996 I moved back to Pixar, where I've worked on rendering, robotics (we built a robot Wall-E to promote the movie) and now "computational cinema", whatever that turns out to be. I'm afraid there's a good chance of some PL and compiler work in my future.

Segmentation fault

Core Dumped.

:)

Seen from GCC.

Actually, the annoying messages are the warnings that a) are of constructs which are *perfectly* harmless, and b) can't easily be disabled. In a shop where the coding standard calls for no warnings allowed, such are annoying.

where the coding standard

where the coding standard calls for no warnings allowed

That is what I always found annoying...

We see this in the PL

We see this in the PL community as well in how we implement our tools, but, perhaps, you were hinting at this already. It's an interesting (flame-baiting?) fine line.

Back on topic, there are two recent projects I found interesting in this space:

1. seminal: http://www.cs.washington.edu/homes/blerner/seminal.html

2. clarify: http://portal.acm.org/citation.cfm?id=1250747

EDIT: this was meant to be a reply to Ehud.

"Missing division or section name"

That was the error produced by the Honeywell 200 COBOL compiler upon reading my student's card deck. In fact, that was the entire output from the compiler; no listing; no hint as to which name was missing.

We riffled through the card deck, reading the interpretation (equivalent of the punched data, printed at the top edge of each card -- hardcore geeks in those days read the holes, but he was a student and I was lazy). Everything appeared in order. Suspecting a possible glitch in the card reader, we ran the compile again.

OBTW, this was a tape-based system, with 8K characters of memory and four mag tape drives. So compiling a program meant mounting the compiler tape (with the write-protect ring removed, of course), along with three scratch tapes, putting your source deck in the card reader, and booting the computer from the compiler tape. After much blinking of console lights lights and spinning of tape drives, again the line printer coughed out a page with a single error message.

Another quick riffle, scanning the interpreted printing, offered no clues.

The student admitted to having worked on his assignment during slack time at his job (a local bank service bureau), including punching at least some of the cards there. Suspecting possible misalignment in one or more cards, I had the student reproduce the deck on one of our state-of-the-art Univac electronic interpreting key punches. An unreadable card would have stopped the device. A successful duplication of the deck would have eliminated any slight out-of-tolerance problems, since we used that keypunch with that computer on a daily bases without encountering this kind of glitch.

Another compile, another one-error-message result.

Stubbornly riffling through the new source deck, I was surprised by a blank card where there should have been a section header! We went back to the student's original deck and discovered that the card in question had been printed with the correct source statement, but contained no holes! (Of course, it was one of the cards he had punched at work.) Although we never discovered the reason that the card had not been properly punched, replacing the blank card with a correctly-punched one allowed the compiler to do something meaningful with his program.

Not only is this my favorite example of a useless error message, it is my only known example, in forty years of programming, of a compile-time error triggered neither by an error in the source code nor in the compiler, but in hardware not part of the system compiling the program.

Archaeological footnote: the description of "8K characters of memory" is neither sloppy terminology nor senility. The Honeywell 200 series (partial clone of the IBM 1400 architecture) treated 8-bit units of memory as a one-bit "record mark", a one-bit "word mark", and six bits of data. Therefore memory was conventionally described as "characters" instead of "bytes". The record and word marks were used to group character data into two-level hierarchical data structures, supported by the machine code. Of course, that was back in the day when almost all manufacturers custom-designed their CPUs, so the idea of a "clone" was slightly disreputable...

Pardon the self-reply...

...but given the less-then-serious tone of the thread, this link seems topically and historically relevant: http://www.youtube.com/watch?v=gdAKgJDahzw

Outside the box

I was doing some Fortran work on a mainframe years ago and I got the message THIS LINE WILL TERMINATE. Alas I did not work out in time that the message didn't come from the compiler, it came from the systems guys, who were about to disconnect my terminal.

Bad Christian!

java.lang.Error: bad Christian! no cookie!
          at * stack trace about 100 frames deep *

In the early OVM days, James Liang and Christian Grothoff sometimes sparred. Deep deep inside of the runtime system, under some very rare circumstance, James defended himself against Christian with this gem.

Unreachable code

By FAR the most irritating error I've ever encountered is from javac. For instance if you want to return from a function early as part of debugging, you'll find you can't:

public void foo() {
  int a = 3;
  return;
  int b = 4;   // error
}


But if you write it like this:

public void foo() {
  int a = 3;
  if (true) return;
  int b = 4; 
}


It works! JavaC is such a stupid compiler it really is aggravating (and yes i know it's because the VM is supposed to do all the heavy lifting)

That's not stupidity

But if you write it like this:

public void foo() {
  int a = 3;
  if (true) return;
  int b = 4; 
}

It works! JavaC is such a stupid compiler

The problem is, you could just as easily have written

if (a == a) return
// or
if (a % 2 == 1) return
// or
if (fourColorTheoremIsTrue()) return;
// or
if (ininiteLoop()) return;

Unreachable code and Metaprogramming

When macros and metaprogramming and compile-time partial evaluation get involved (e.g. in C++) the ability to say 'if(true)' and 'if(false)' without complaints from the compiler becomes quite useful. Not that this applies so much to Java...

What's prevent us from getting better error messages?

In the mid-80's, I was the QA person for LightspeedC and Lightspeed Pascal for the Macintosh (which later was renamed to ThinkC and ThinkPascal.)

What I did, was look at every error message and wrote sample code that would generate the error. After creating a substantial body of malformed code for testing. If I thought the error message wasn't clear, I would say so and push for improvements.

Furthermore, it was a small leap to create an error message appendix with useful examples and brief, but non-redundant explanations. Some explanations were a sentence or two, but others such as "Syntax Error" would run several pages illustrating the various causes of that annoyingly vague error message.

My first effort with LightspeedC, yielded 26 page appendix. My second effort resulted in a 66 page (8.5x11) appendix. This appendix was greater in size since Pascal is a more complex language and I had developed greater confidence.

Part of what I was also trying to achieve was a reduction in customer support calls too.

Why can't this be done more often?

Thank You!

I recall the ThinkPascal error message appendix from a high school CS course. Extremely useful, and a wonderful way to learn more about the language bit-by-bit without having to read a dry spec. Thank You!

I just got this

invalid conversion from 'int(*)()' to 'int(*)()'

If it's from GCC, that one

If it's from GCC, that one usually means that you're passing a function pointer to a context that expects a different calling convention. For example, passing int foo() to code that wanted an int WINAPI foo(). On some OSes I think you can also get it if you pass an extern "C" function where an extern "C++" one was expected, or vice versa. GCC apparently neglects to mention the calling convention when it displays a function signature in an error message.

Does extern C/C++ matter for the type of a function in C++

I've never heard of that behavior; I was under the impression that the effect of "extern C" was simply to disable name-mangling.

Of course, there are other things that C++ can do in a function signature that C cannot--reference parameters and exceptions being the two biggies... gcc doesn't seem to mind declarations like this, though:

extern "C" void foo (int &arg);

Type Error

Reading this thread has me half tempted to replace all error messages in BitC with the string "type error". This is a context dependent error. Depending on context it either means that you typed something wrong or that something was wrongly typed... :-)

If you're aiming to be truly frustrating

If you're aiming to be truly frustrating, you should go for the PL/I F compiler style of error reporting: attempt to automatically correct the code via coercions or additions, then report only the errors that result from these automatic corrections.

Then sort the errors by severity before position in program so that a errors from a single point will be scattered across the error report.

If that doesn't do it for you, you may go ahead and make the reports vague or ambiguous.

Of course...

aborting the compilation after the first error is discovered has got that beat.

True... especially if it

True... especially if it doesn't report information on the error.

Apple MPW C errors

Many years ago on Usenet, someone posted a list of favourite error messages from Apple's old MPW C compiler...

  • "String literal too long (I let you have 512 characters, that's 3 more than ANSI said I should)"
  • "...And the lord said, 'lo, there shall only be case or default labels inside a switch statement'"
  • "a typedef name was a complete surprise to me at this point in your program"
  • "'Volatile' and 'Register' are not miscible"
  • "You can't modify a constant, float upstream, win an argument with the IRS, or satisfy this compiler"
  • "This struct already has a perfectly good definition"
  • "This onion already has a perfectly good definition"
  • "type in (cast) must be scalar; ANSI 3.3.4; page 39, lines 10-11 (I know you don't care, I'm just trying to annoy you)"
  • "Can't cast a void type to type void (because the ANSI spec. says so, that's why)"
  • "Huh ?"
  • "can't go mucking with a 'void *'"
  • "we already did this function"
  • "This label is the target of a goto from outside of the block containing this label AND this block has an automatic variable with an initializer AND your window wasn't wide enough to read this whole error message"
  • "Call me paranoid but finding '/*' inside this comment makes me suspicious"
  • "Too many errors on one line (make fewer)"
  • "Symbol table full - fatal heap error; please go buy a RAM upgrade from your local Apple dealer"

I never saw this myself, but ...

... it's claimed that an MS-DOS port of Awk once existed that had the error message "Not enough memory to do jack: terminating".

It's not a compiler error, but the famous HODIE NATUS EST RADICI FRATER surely belongs in any compilation (ha!) of famously unhelpful errors.

intel ISR error description

Since others have contributed somewhat off topic errors, let me add a favorite of my own. Compiler writers who have spent long hours with the Intel instruction set reference manual may have noticed this wonderful description of a potential error state when executing the PUSHA instruction, which saves several important registers to the stack:

In the real-address mode, if the ESP or SP register is 1, 3, or 5 when the PUSHA/PUSHAD instruction is executed, the processor shuts down due to a lack of stack space. No exception is generated to indicate this condition.

This is, perhaps, the least helpful error message possible. Also, what if ESP is 2 or 4?

Gaping wound in control stack

Not "most annoying", but worth mentioning:

"Control level closure leaves gaping wound in control stack."

-- Clipper 5.0 compiler

This could happen when control structures (e.g. IF/ENDIF) weren't properly closed.

I didn't see anyone

I didn't see anyone mentioned ie's javascript messages:

object expected

Seen yesterday from GCC

Upgraded my Ubuntu install from 8.04 to 8.10, which included a new version of GCC (4.3.2), one which adds (more) support for the forthcoming C++0x standard.

My code uses some nonstandard but ubiquitous parts of the standard template library--hash_set and the like--which are being standardized by c++0x, under the name unordered_set.

So when I compile under 4.3.2, I get the helpful warning from the compiler all over the place:

#warning This file includes at least one deprecated or antiquated header which may be removed without further notice at a future date. Please use a non-deprecated interface with equivalent functionality instead. For a listing of replacement headers and interfaces, consult the file backward_warning.h. To disable this warning use -Wno-deprecated.

which I quickly determined to refer to hash_set.

So I modified my code to use the new, soon-to-be-standard library, and get:

This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.

The second warning I don't mind so much, especially if the implementation of the new standard isn't fully debugged. But deprecating something before its replacement is production-ready seems to be a Silly Thing To Do...