
“It is never a compiler error” - zeveb
https://blog.plover.com/2017/11/12/
======
cperciva
Sadly, I've lost count of how many compiler bugs I've tripped over through the
years. Often it's compiler crashes -- those are usually easy to get fixed,
especially when (as tends to be the case with LLVM) they are caused by
assertions failing -- but I've also tripped over compiler _hangs_ (there's a
variable in the tarsnap code with an utterly bogus volatile specifier in order
to avoid the problematic optimization on some versions of llvm) and outright
_miscompilations_ \-- one of which has had several LLVM bug reports opened by
different people over the years and remains unfixed.

~~~
empath75
If you’re the kind of programmer who is likely to find compiler errors, you
probably know who you are. For 99% of programmers, the chances that you have
discovered one is small.

~~~
gioele
> If you’re the kind of programmer who is likely to find compiler errors, you
> probably know who you are.

I'm one of those that routinely find a bug in a library during the very first
use of its API. Every "quick weekend project" turns into "let's learn the
build system of this library and send a patch/bug report to the maintainer".

Does anybody know how can I turn this annoying superpower of mine into a job
that is not basic Q/A?

~~~
ggm
<quote>Does anybody know how can I turn this annoying superpower of mine into
a job that is not basic Q/A? </quote> What would you say, if I told you that
this superpower was not basic Q/A? because basic Q/A is what the compiler is
passing, all the time. The part you meant with vigour was the <b>job</b> part
right? how do you make somebody want your awesome enough to pay you a living
wage? It's either apple or Intel, because they are the two people financially
vested in llvm.

~~~
amake
If you're the kind of programmer who inputs HTML into a comment system that
doesn't support it...

~~~
ggm
I'm not in QA. You obviously head the snark department very well. Expect
promotion, but alas, not much more pay.

------
CobrastanJorji
When I was just getting into the industry, I was offered a job from a team at
IBM, working on some OS or other whose name I forgot. I was chatting with the
head developer about the workflow. He told me that, as the OS was written in a
custom programming language, and the OS was the only program ever written in
this programming languages, they found that roughly 50% of the bugs they
encountered were in the OS code, and roughly 50% were in the compiler for the
OS code.

I very politely finished the interview and then ran away as fast as I could
and never looked back. I did not need that shit in my life. The world where
it's always my fault is a better place.

~~~
ptr
If you hadn't mentioned IBM, I would've guess this was Bell Labs, Unix and C.

~~~
SwellJoe
IBM has built several operating systems and programming languages and
compilers over the years. Probably more than Bell Labs, actually. It's not so
surprising.

~~~
ejolto
Unix and C is more known, so that would be my assumption too. In fact I can't
name any IBM made OSes or programming languages.

~~~
ecshafer
Aix and z/os are popular operating systems by ibmsl still in use, not counting
things like system/36\. Lime is a research pl at I'm, there is also apl which
was made at Harvard and later at ibm.

------
nathan_long
This is great advice, but needs a caveat. I'd say it this way:

 _The less battle-tested a part of the stack is, the more likely it is to
contain a bug._

Suppose I'm using a database library written in Elixir to run a PostgreSQL
query and I get a weird result. Where is the problem?

PostgreSQL has executed billions of queries in thousands of projects for tens
of years and has many contributors.

The Elixir library is much newer and has many fewer contributors and has been
used much less.

My brand-new query has been executed a handful of times by me and has only
been looked at by me.

The chances are overwhelmingly high that the bug is in my code. If I can't
find it there, the next candidate is the Elixir library. Only after exhaustive
search in those two should I consider that PostgreSQL may have a bug.

Or to include more of the stack:

    
    
        my code > Elixir lib > Elixir > Erlang > PostgreSQL
    

The author's own anecdote with finding a bug in JavaScript's `sort()`
illustrates this principle: it was not in (say) the Firefox or Chrome JS
interpreter, but in a much less-used one: [https://github.com/code-dot-org/JS-
Interpreter/pull/23](https://github.com/code-dot-org/JS-Interpreter/pull/23)

~~~
dnautics
I definitely found a compiler error in an early version of Julia, luckily the
solution was to upgrade to the newer release that I'd been too lazy to bump
to.

~~~
nathan_long
Good example. "An early version of Julia" is a less-tested piece of your stack
than, say, "a recent version of Java". Especially if the feature in question
is something absolutely everyone uses in Java.

~~~
dnautics
And the feature with the bug is a little-used part of julia

------
PaulJulius
The new implementation is still wrong, according to the specification.

Array.prototype.sort does not sort an array of numbers as expected. In
JavaScript, [2, 10].sort() results in the array [10, 2].

As MDN points out, "The default sort order is according to string Unicode code
points... If [compareFn is] omitted, the array is sorted according to each
character's Unicode code point value, according to the string conversion of
each element." [0] It has an example showing off the unintuitive behavior
right at the top of the page.

This behavior is intended per the original ECMAScript specification[1, pg.
68]:

    
    
      When the SortCompare operator is called with two arguments 
      x and y, the following steps are taken:
      1. If x and y are both undefined, return +0.
      2. If x is undefined, return 1.
      3. If y is undefined, return −1.
      4. If the argument comparefn was not provided in the call 
         to sort, go to step 7.
      5. Call comparefn with arguments x and y.
      6. Return Result(5).
      7. Call ToString(x).
      8. Call ToString(y).
      9. If Result(7) < Result(8), return −1.
      10. If Result(7) > Result(8), return 1.
      11. Return +0.
    

The key points are items 4, 7 and 8.

[0] [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)

[1] [http://www.ecma-international.org/publications/files/ECMA-
ST...](http://www.ecma-international.org/publications/files/ECMA-ST-
ARCH/ECMA-262,%201st%20edition,%20June%201997.pdf)

~~~
mar77i
What an awful gem of surprising by design.

Definitely going to add this to my contempt for javascript list.

~~~
fenomas
It's the worst option except for all the others, I think. JS arrays can
contain anything, so if the default behavior was to compare elements as
numbers, sorting an array containing mixed types would have unpredictable
results (because of comparisons to NaN, etc).

Naturally things are only weird for untyped arrays - calling sort() on e.g. an
Int32Array does what you'd expect.

~~~
sullyj3
Python throws an exception for incomparable types. I guess that's not really
practical on the web.

~~~
TremendousJudge
why is it better to silently fail than to throw an exception simply because
it's running on a web browser?

------
pjungwir
Back in 2010 I wanted to try out Scala. I fired up the REPL and did this:

    
    
        scala> 1+2
        res0: Int = 12
    

Here is a blog post I wrote about it at the time:
[https://illuminatedcomputing.com/posts/2010/11/no-luck-
tryin...](https://illuminatedcomputing.com/posts/2010/11/no-luck-trying-out-
scala/)

I was running under Cygwin and the issue was something about the Java-based
readline library.

I filed a ticket (linked in my blog post but the link is broken now), but the
maintainers' response was something like "Yeah right. Closed."

You'd think compiler bugs would be more obscure than 1+2. :-)

~~~
goialoq
What's old is new again:

[https://www.google.com/search?q=ios+1+2+3](https://www.google.com/search?q=ios+1+2+3)

~~~
saagarjha
This isn't related…

------
thisrod
I seem to be cursed with the ability to crash any language interpreter I play
with. My favorite so far was when I tried Smalltalk, mixed up / and //, and
asked for a window that was 3/2 pixels wide (maybe not 3/2, but some non-
integer rational width). The maintainers: "Wow! That bug must have been
lurking in the bytecode interpreter since Xerox PARC."

~~~
FascinatedBox
You might think this is a curse, but as someone writing a language, people
like yourself are a blessing. Exercising the weird cases that the original
people overlooked and filing a bug is really, truly helpful.

------
philipkglass
I have worked in a domain where "it is often a compiler error" \-- scientific
simulation. In particular, Intel's C and Fortran compilers generally produce
the fastest binaries on Intel hardware but they also seemed to break builds a
lot. The answer to "the validation suite no longer passes" was often "use this
specific point release of the compiler."

I wasn't personally developing the core simulation software itself at the
time, just building it from source and writing extensions. I don't know if
these frequent breakages were actually outright compiler bugs or just relying
on conventions that weren't guaranteed by language specs. But I do know that
switching to one particular blessed compiler revision was often the fastest
way to pass validation and move on to your actual research problems.

~~~
frivoal
Having to use a specific point release of the compiler to work does not
necessarily means later version have a bug. It could also mean that the
program is (accidentally) depending on implementation details that are not
guaranteed by the language, and that the compiler is supposed to be free to
change behavior about. For languages like C with a significant amount of
undefined behavior, that's actually quite likely.

------
davidbanham
I was lead on a project that was making heavy use of the HTML5 filesystem API.
We were transiting multiple GB through the API in a single session.

The program had a memory leak. It was about the same whether it was deployed
through Cordova on iOS or node-webkit on OSX or Windows.

There was a _lot_ of code in this thing. A lot of code within the content
(which was written by another vendor) and a whole bunch of code in our wrapper
that was there to emulate legacy behaviour of the old ObjC app it replaced.

We assumed the leak was somewhere in our code or the other vendor's code. We
spent _months_ trying to figure this thing out. I spent countless hours
looking at heap dumps. Going over every bit of dumb code to try and figure out
what was wrong. This was a big undertaking with a lot on the line from our
client.

Then one day we upgraded the version of node-webkit. It happened to include a
newer build of webkit. The bug _vanished_ on the OSX and Windows builds. That
was our big break. All of a sudden the possibility of a compiler bug was on
the table.

We ended up tracking it to a bug in webkit's implementation of (iirc) the
html5 filesystem API. Nobody used it much and as far as I can tell, we were
the only ones using it as heavily as we were.

Happy days for OSX and Windows, but the iOS build was still horrible because
iOS was using a webkit build from before the patch.

We begged and pleaded with Apple to give us some indication of whether or when
the build would be updated. wkwebview came and it was still busted.

The project ended up being closed down, in no small part due to the iOS bugs.
I moved on. I have no idea to this day whether or not the iOS build has been
updated or not.

~~~
Cacti
You sure this wasn't just karma for attempting something as absurd as using
Node and HTML5 FileSystem in a native iOS app?

BTW, what you're talking about isn't a compiler error.

~~~
wgjordan
> BTW, what you're talking about isn't a compiler error.

Neither was the blog post:

> [ Addendum 20171113: Yes, yes, I know sort() is in the library, not in the
> compiler. I am using "compiler error" as a synecdoche for "system software
> error". ]

~~~
Cacti
That's not even what that word means.

~~~
phaemon
Yes it is. A "synecdoche" is where you use a part to refer to the whole (or
vice versa).

------
qwerty456127
"The compiler did not have a bug. The compiler never had a bug. The bug was
always in the programmer's code and usually in their understanding of the
language... It was caused by a misunderstanding of the way arguments to
unprototyped functions were automatically promoted..." \- I'd say the bug is
neither in the compiler nor in their understanding of the language but in the
language itself then. Why on Earth do we need a language that we can't use
safely without "understanding of the way arguments to unprototyped functions
are automatically promoted"? IMHO the number-one principle to be followed in
every sane language design is the "principle of least surprise" (POLA). If the
language can surprise you easily and lets you write weird code that is going
to work a way different from what one will probably assume intuitively -
that's a language made wrong.

~~~
ajross
> Why on Earth do we need a language that [...]

Have someone sit down with you and explain how slow computers were in the
1970's. C won because it could be efficiently implemented on everything,
produce better code than pretty much anything else, and still produce
effective software quickly. And everything after that is a network effect
because of all the inherited C.

Your complaint has been repeated ad nauseum by literally generations of
programmers who simply can't imagine why everyone did things this way, and who
then go on to productive careers writing or integrating or just living with
software still written in C.

If you want to change the world, you need to stop pontificating and roll up
your sleeves. There's a whole lot of code to write in rust, or whatever your
particular brand of zealotry demands.

~~~
wbl
Mainframes had bounds checks. It didn't cost much, but C omitted them. Some of
the undefined behavior in C particularly around accesses and overflow could be
changed to implementation defined to fix some of the more footgunny parts.
Until C 99 C could not vectorize nearly as much as Fortran. C won because of
Unix network effects and the PDP, not because it was that good a choice.

~~~
ajross
Surely someone had checked loads. The IBM 360/370 did not (unless it was some
optional thing they sold -- certainly it wasn't part of the basic
architecture), so "mainframes" seems rather spun. Likewise, yes, C's floating
point calling conventions sucked and Fortran continued to see use in numerics
work for a long time. But at the same time no one was writing performance-
sensitive vector code for their Cray's in high level languages, ever. And
frankly no one even thought to until GPUs made low level code impossible.

I'll say it again, C won because:

1\. Compilers could be (and were!) written for any byte-addressible
architecture by one hacker in a basement...

2\. ...that produced output code quality comparable to what you could get
anywhere else in the industry

3\. ...and take advantage of the huge community of C hackers.

Different languages running on supercomputers and non-360 mainframes wouldn't
have changed any of that.

~~~
wbl
1 and 2 also seem true for Pascal. Network effects are important but they
would have worked for any language. Tony Hoare discussed bounds checking on
the Burroughs mainframe.

------
pedasmith
I've only ever hit one compiler bug that was really a bug: a C compiler for
6805 microcontrollers would only produce a correct function-start if the
function took 2 bytes or less of arguments. That particular project includes a
surprising number of global variables :-)

Not a "compiler bug" but a "gosh I wish some people who are working on a
project voluntarily that I'm not paying for would do a crap-load of work"
bucket: for a while GCC could either compile a program with threads or with
exceptions. If you had both threads AND exception code (even if you never
threw an exception), the emitted code would eventually crash.

------
krylon
About 9-10 years ago, I worked at a company maintaining an application written
in C. There were three other programmers there who had been with the company
from the beginning, which at the time was ~15 years. They used the OpenWatcom
compiler.

A few days in, I discovered that they compiled all their code with all
compiler optimizations disabled. They had done so ever since they encountered
a bug in the compiler/optimizer where the compiler would somehow think that a
boolean expression involving floating point numbers in the head of an if-
statement would always evaluate to true or false and thus optimize away either
the if-part leaving only the body, or remove the whole if-statement.

I did a little bit of research and found what I think was that bug in the
release notes to an earlier version, but even so the other programmers were
adamant in keeping optimizations disabled.

(FWIW, I once did a build with all reasonable optimizations enabled, and the
improvement was miniscule. Either our code sucked so hard the optimizer could
not do much about it, or it was so good there was nothing left for the
compiler to optimize. I doubt it was the latter, though. ;-) )

~~~
JoeAltmaier
...or the compiler had a worthless optimizer?

~~~
krylon
Maybe.

Watcom used to have a reputation for generating fast code, but that was in the
1980s, early 1990s. The impression I got was that by the time I started
working at that company, OpenWatcom was mostly around because it was very good
for compiling code for DOS.

It supported all of those weird memory models from the days of segmented
memory, it had its own 32-bit protected mode which I assume many programmers
back then welcomed enthusiastically.

Plus, I read somewhere that OpenWatcom is practically the only compiler that
can create DOS executables to be stored in ROM (for embedded / industrial
applications, I guess). Or something like that.

------
mehrdada
Well, we've found quite a bunch:
[https://mehrdad.afshari.me/publications/compiler-
validation-...](https://mehrdad.afshari.me/publications/compiler-validation-
via-equivalence-modulo-inputs.pdf)

~~~
Twisol
I immediately thought of this work when I saw the title. Of course, you're
actively and effectively hunting down bugs, not accidentally running into them
while doing other things ;)

~~~
mehrdada
Yes, but for example I remember at least one anecdote where one of our bugs we
encountered was closed as a bug that manifested itself as a crashing bug in
x264 or ffmpeg (I forget which) and ours was closed as a duplicate, so people
do actually encounter bugs.

------
8fingerlouie
Back when i wrote software for GSM mobile phones (2000'ish), we spotted
several compiler errors in our "Infineon E-Gold" C compiler.

If you declared something like :

    
    
        int a = 1 + 2 + 3;
    

The result would simply be "a=3". Turned out the compiler threw out any
argument besides the first two.

Another error would be the compiler failing to increment the segment pointer
(16 bit platform), and the offset pointer simply wrapped around. This didn't
show itself until we added a new 120x90 pixel four color display, meaning our
display shadow buffer grew to a staggering 20 KiB, and depending on the build,
the display buffer would become corrupted.

Certification for GSM compilers is expensive, so we just learned to work
around it, i.e. we reimplemented our stdlib memcpy, memmove, strcpy, etc
functions in assembler.

~~~
dfox
Wrapping of offset pointers in this manner is usually an (documented) feature
not a bug. At least on DOS compilers, where this is also usually configurable
(this is part of what "C memory model" option of 16bit DOS C compilers is
about).

~~~
8fingerlouie
The company closed the Danish branch in 2003, so it's been 15 years, and i
can't remember the compiler options we used, but we looked deeply into the
problem back then, and it was acknowledged as a compiler error (at the time).

the offset pointer problem however was the least troublesome. The problem with
disappearing arguments took a long time, and a lauterbach hardware debugger to
figure out :)

------
outworlder
This goes for other things as well, not just compilers.

As of this moment I am begrudgingly creating a support ticket with AWS for an
issue which I am 99.99999999% confident is in our VM and has nothing to do
with AWS itself.

For some reason, "AWS issues" is one of the first things raised, even though
we are unlikely to be hitting AWS edge cases, not being Netflix-scale.

Honorable mention: "Kernel issue"

~~~
deathanatos
AWS is nowhere near as reliable as a compiler. We've seen things ranging from
"S3 intermittently takes 60 or 120 seconds (or some multiple thereof)" (but
apparently only for my buckets…) to spatial indexes in Aurora just flat out
didn't work when they were released, to S3 acknowledges writes prior to them
being available to be read (causing a reader who picks up the item to receive
a 404), to ELBs corrupting the HTTP connection depending on packet timings.

That's aside from the more common issues of "this VM is just going to bite the
dust", which is something I feel is just inevitable.

The kernel is more reliable, IMO (except when it comes to the Thinkpad
TrackPoint drivers).

~~~
openasocket
> S3 acknowledges writes prior to them being available to be read (causing a
> reader who picks up the item to receive a 404)

That's exactly documented behavior:
[http://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction....](http://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html#ConsistencyModel)

~~~
deathanatos
Huh. TIL. I swear we searched the docs when we ran into that, and found the
same consistency guarantee minus that rather large caveat, but Wayback says
that was there at the time. Perhaps we were looking at a different page, but
it does appear this is and was documented behavior.

That's a hugely unuseful caveat in practice though. I'd really love to have
consistent reads.

------
joe_the_user
Of course, there's also the point that if utterly pathological behavior is
documented, then it's not a compiler error. I remember a c++ compiler that had
a hard limit on the number of objects allowed in the programs it compiled.
It's documented, "not an error".

The compiler actually crashes rather than returning anything? Well, that's
more likely to happen when your code has lots of errors in it. "Don't look at
me like that. Go fix your code and then come and complain..."

------
ridiculous_fish
Three compiler codegen bug war stories:

1\. libdivide found a gcc 4.8 vectorizer bug in high multiplies.
[https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61108](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61108)

2\. Circa 2001, I decided to learn Java. My first-ever Java program performed
a right shift by -1 (for some reason I can't recall but was probably really
stupid). The spec requires this to be equivalent to >>31, but the compiler
wrongly optimized it to >>0\. My confused post can probably still be found in
comp.lang.java.help.

3\. I wrote a Python script that generated a large set of test cases for an
FFI (NSInvocation). The test crashed inexplicably on PowerPC64 with a nonsense
backtrace. Turns out the PPC64 jump instruction has a 24-bit literal offset,
and my functions were so large they overflowed it. That got fixed (also in
gcc).

------
kod
Funny that he mentions that any bug in perl's if statement would be caught
within a year.

I had a project that lost $150,000+ because of a bug in perl's sprintf (but
not printf, mind you).

[https://rt.perl.org/Public/Bug/Display.html?id=82418](https://rt.perl.org/Public/Bug/Display.html?id=82418)

Yep, that ticket was open for well over a year.

~~~
jandrese
We just had the article on what a nightmare Unix Locale is.

------
dcminter
I dislike the glossing over of the distinction between a compiler bug and a
library bug. For me there's a definite spectrum:

* OS - I've never found an OS bug that wasn't widely known

* Compiler - I've found 2 compiler bugs in my career to date (both of which crashed the compiler, making this very clear cut)

* Standard libraries - I've found a moderate handful of bugs in standard libraries, somewhat proportionate to the code surface.

* Third party libraries - I rarely use a third party library without exposing a bug.

* Applications - I find bugs in almost all of the applications that I use.

* My own code - Most of my professional life is spent debugging my own code.

------
readittwice
> The sort() function was using a bubble sort. (This is of course a bad
> choice, and I think the maintainers plan to replace it.)

There are some valid use cases for Bubble Sort for small and almost sorted
arrays (although Array.prototype.sort sounds like a very general solution,
which I suppose is not a good idea). I've seen this in JavaScriptCore where
they use Cocktail Sort (a variant of Bubble Sort) for sorting in some
situations. They also added some performance numbers and explanation in [1]
that show that it's faster than e.g. std::stable_sort. I actually tried to
write an Insertion Set (which is supposed to be better than Bubble Sort), but
couldn't get it to perform better than their Cocktail Sort implementation.

[1]
[https://github.com/WebKit/webkit/blob/master/Source/WTF/wtf/...](https://github.com/WebKit/webkit/blob/master/Source/WTF/wtf/BubbleSort.h#L31)

~~~
varjag
Doubt whoever wrote the library sort() was optimizing for long tail use cases.

------
VBprogrammer
My favourite bug came from a university assignment on autonomous robotics. We
had to build a small robot using various sensors, such as some whiskers which
could be used to detect some metallic tape stuck to the floor of the arena.

One of the other teams found that their robot kept freezing after a few
minutes of moving around the arena, I assumed this was due to exhausting
available file handles or some other bug in their code. But after some time
they realised that the bug only happened when the metal castor they had used
on back of their robot touched the metallic tape.

Sure enough, when they replaced the castor with a bit of lego their robot
continued to run perfectly for the duration.

The lego construction of the robot must have been building up some static
charge which was then discharged when running over the metallic tape and
taking out the ARM computer when it did so.

I'd have never believed that one unless I'd seen it with my own eyes.

------
mdhughes
When using a new version of a compiler, and existing code stops working, it is
often a compiler error. When different compilers give different results, it is
often a compiler error.

I've hit dozens or hundreds of these, across many languages for decades.

It's not the _first_ thing to check, but once you verify the code is logically
correct, that can be the only conclusion.

Compilers aren't excessively complex code, but _all_ code has bugs.

~~~
kbenson
> When using a new version of a compiler, and existing code stops working, it
> is often a compiler error. When different compilers give different results,
> it is often a compiler error.

To be fair, sometimes that's because the compiler became more strict and your
code had an error that wasn't being caught. Sometimes it's the compiler taking
a more liberal stance on what "undefined behavior" is for performance reasons.
In both cases, that would still a programmer error (and I think those are
likely the more common case than an actual compiler error).

------
Agentlien
At my previous job a colleague showed me some C++ code and asked if I could
help him spot the issue. I looked at it and said it looked fine. He ran the
program and it crashed.

We ended up staying late in order to try to find a minimal reproducible
example. We finally managed and found that the cause was a basic trigonometric
function in the standard library giving the wrong result.

At first, we couldn't believe it. Then we googled the issue and found a bug
report about the intrinsic version of that function not working properly. With
Microsoft confirming that it didn't and that they weren't looking to fix it.
We disabled intrinsics in that section of the code and the original code
worked as intended.

------
scraft
I have hit a number of C/C++ compiler bugs in GCC, MS VC, Code Warrior and
various in other languages (for example shader compilers). I agree it is the
sort of the last thing you blame, but at the same point, sometimes it really
is, so I get a couple of sanity checks from skilled friends or colleagues,
making a tiny repro, submit and move on!

------
alpb
Am I the only one who was expecting to read something about compiler errors
but instead found an article about a bug in a JavaScript polyfill library?

------
bdamm
Certainly I've seen compiler bugs.

1) Borland Turbo Pascal, where code would not execute correctly in the
presence of a comment near the top of a loop. Deleting the comment caused the
correct loop execution.

2) Texas Instruments DSP C-compiler sometimes failed to unroll loops
correctly. Certain loop forms needed to be avoided as a result.

3) Recently I've been working on a C-compiler written in Golang, and the
grammar definition was raw enough that it definitely had bugs. The bugs were
fortunately obvious in that it would refuse to compile valid C code.

Of course, 99.98% bugs were mine.

------
blt
I'm more shocked that bubble sort is used in production somewhere...

~~~
harry8
I think we need to get away from this attitude, that I used to hold, that O()
is everything. It isn't. It isn't even close. We should instead wonder why an
algorithm was chosen without regard for the nature of the data on which it
will be applied. For sorting O(n lg n) only makes sense as a selection
criteria if you have absolutely no idea about what data is being sorted. Why
is that?

If the answer is you just don't care about the perfromance and can say why it
isn't important (at least yet) as long as you avoid the pathological then
that's a good answer. It's a really bad answer to assume it when you can't.
IMHO.

Others have pointed out that bubble sort is great when your data is already
mostly sorted. The textbook example is check stub ids, which are sequential -
probably an outdated example nowadays. The benefit is greater than a O()
analysis would have you believe because running sequentially through
contiguous memory is something computers are just great at doing due to memory
caching and prefetching. Minimising cache misses /may/ dominate the number of
passes of the data in performance analysis. If you don't care about
performance then an O(N^2) algorithm may be also something you don't care
about.

~~~
Jach
You're misidentifying the attitude. The problem is that Bubble Sort is a
terrible algorithm, there's no reason not to use Insertion Sort or better
instead except for some reason CS programs still inflict BS on students so
that's what they remember when they just need to sort something.

[http://warp.povusers.org/grrr/bubblesort_eng.html](http://warp.povusers.org/grrr/bubblesort_eng.html)

[http://warp.povusers.org/grrr/bubblesort_misconceptions.html](http://warp.povusers.org/grrr/bubblesort_misconceptions.html)
(Bubble sort is not great when your data is almost sorted. Insertion sort is,
though.)

~~~
harry8
To the second link

"Bubble sort always performs n-1 passes through the data (where n is the
amount of elements), and it always performs (n-1)+(n-2)+...+1 comparisons
regardless of how the data is organized to begin with."

That is just false. 1 pass and n-1 comparisons then stops for already sorted
data is what you get. An implementation that doesn't show that characteristic
has been either deliberately or accidentally pessimized to behave poorly. You
can gimp any algo to make it look bad. Quicksort without randomization on a
pathological case is O(n^2) for example and nobody cares for the overwhelming
majority of practical purposes. If your definition of bubble sort is that it
must be O(n^2) always then we're not using "bubble sort" to mean the same
thing and it's pointless to continue the discussion.

Bubble sort is usually operates on data in place. I don't know how to do an
efficent in-place selection sort for mostly sorted data, maybe it's possible?
You pay for additional copies in both space and cpu cycles. 2xn space for
selection usually - but maybe this can be avoided without paying a very high
time overhead, (eg find the spot, ripple all data below the spot down to the
hole where you selected to open a slot for insert or similar).

Count the memory operations, ie number of memory reads and number of memory
writes for a given set of data comparing the two algorithms.

Suggestions: Write 50 odd lines of C code to see the actual effect in cpu
cycles. Craft data to make each algorithm dominate the other, it's really
interesting to see.

I'm disinclined to say "Never uses algo X, always use algo Y!" Because it's
really hard for that to be sensible given all the various shapes and sizes
input data takes. Know your data is always really, really good advice.

~~~
openasocket
> Bubble sort is usually operates on data in place. I don't know how to do an
> efficent in-place selection sort for mostly sorted data, maybe it's
> possible?

What about insertion sort? Which always performs fewer comparisons and swaps
than bubble sort for any array, by the way.

~~~
harry8
So I made the case with evidence that it doesn't always perform fewer
comparisons and it it doesn't always perform fewer swaps. While it probably
does, depending on implementation details use more memory. Do feel free to
actually make your case with evidence, that I would be interested in reading.

What is it with this thread and "nyer, you're wrong" responses? It's not
helpful, not clever, not useful and not pleasant to read for anybody. Finding
out you're wrong is great, I learn stuff.

~~~
openasocket
> While it probably does, depending on implementation details use more memory

Have you actually looked at the insertion sort algorithm? It doesn't allocate
any additional memory. Neither does bubble sort or selection sort.

Knuth does some analysis of Bubble Sort in Volume 3 of the Art of Computer
Programming, which proves bubble sort performs more comparisons and more swap
operations than insertion sort. To quote the conclusion: "[A]lthough the
techniques used in the calculations [to analyze the bubble sort] are
instructive, the results are disappointing since they tell us that the bubble
sort isn't really very good at all. Compared to straight insertion […], bubble
sorting requires a more complicated program and takes about twice as long!"

~~~
harry8
1,2,3,4,6,5,7

6 comparisons, 1 swap with bubble and it stops. I make it 7 memory reads and 2
memory writes.

Insertion and selection sorts are going to run in half that time? I'd really
like to see that! I think Knuth might be talking about a general case of _any_
data rather than the topic being discussed here, but no, I haven't read Knuth
on bubble sort so I can't be sure. I may do so now so thank you for the
pointer. Arguments from authority really can be informative and useful despite
their other shortcomings.

~~~
openasocket
Bubble sort performs 11 comparisons and 13 memory reads in this case,
actually. Because on the first pass through the array it performed a swap, it
has to loop through the array a second time to verify the array is completely
sorted.

To avoid confusion, here's the bubble sort algorithm:

    
    
      procedure bubbleSort( A : list of sortable items )
        n = length(A)
        repeat
            swapped = false
            for i = 1 to n-1 inclusive do
                if A[i-1] > A[i] then
                    swap(A[i-1], A[i])
                    swapped = true
                end if
            end for
            n = n - 1
        until not swapped
      end procedure
    

As you can see, after performing a swap during the first pass through the
array it has to go through again (though it can skip the last element because
we know the last element must contain the largest element in the array)

Insertion sort will perform 7 comparisons, 1 swap, 7 memory reads and 2
writes.

~~~
harry8
You can avoid the second pass...

~~~
openasocket
No, you can't, because at the end of the first pass you have no way to know
that it is in sorted order. Go ahead and try to write the pseudocode for your
bubble sort implementation that avoids the second pass.

~~~
somecontext
To be concrete, the array in order 1235647 has the first six comparisons go
the same way as in 1234657, but it doesn't end up sorted in one pass.

Perhaps harry8 was thinking of the bubble sort implementation in the OP, which
would indeed stop after one pass in these cases.

------
FullyFunctional
I still remember my First Time. As a very novice coder (it was in the 1980s so
I was young) I was using Microsoft C 3.0 (I think) and couldn't believe my
program didn't work. It took understanding the assembly to discover that it
was a compiler bug. It shook me to the core; before I had never even imagined
that something like this could be wrong.

I later did find bugs in GCC (version ~ 1.37), but since it's pretty robust
these days, notably the regression suite is a lot better than it used to be.

------
Animats
Finding library bugs, though, is routine. Most languages today come with a
large collection of libraries, most of which work for the common cases. In an
API with a thousand calls, probably at least 5% of them have major bugs.

------
lloeki
Just a week ago I remembered reading an article several years ago about
someone who ended up digging in the compiler (probably GCC) and against all
odds unearthed a bug in there. As I recall it was quite involved and an
interesting read but I can’t seem to find it again. If anyone has a
recollection of such an article I’d be grateful to be sent a link in my
general direction.

------
xelxebar
The article mentions another Coding Horror one at the bottom [0]. I found this
tidbit from there interesting:

"In Code Complete, Steve McConnell cited two studies that proved it:

"A pair of studies performed [in 1973 and 1984] found that, of total errors
reported, roughly 95% are caused by programmers, 2% by systems software (the
compiler and the operating system), 2% by some other software, and 1% by the
hardware. Systems software and development tools are used by many more people
today than they were in the 1970s and 1980s, and so my best guess is that,
today, an even higher percentage of errors are the programmers' fault."

I'd really like to learn how to track down hardware bugs, or mess with things
like Christopher Domas does.

[0] [https://blog.codinghorror.com/the-first-rule-of-
programming-...](https://blog.codinghorror.com/the-first-rule-of-programming-
its-always-your-fault/)

~~~
mark-r
There's a story I heard that I can't track down anymore, about a game company
that kept getting strange unreproducible errors from customers. They built a
RAM test into their game and discovered that most of those errors were coming
from bad RAM. 1% of a lot is a lot!

~~~
zlynx
Doom 3 inadvertently did this for me one time. It loads data from pak/zip
files and does a checksum verification. Which is how I discovered a defective
RAM stick I'd used in a new system build.

------
Lerc
The only error I found where the code compiled but was wrong was from it
assuming a particular symmetry in the instruction set. It tried to use an
addressing mode on an instruction that didn't support it and consequently
output two completely different instructions.

Errors in the run-time library and errors that crash the compiler are much
more common. While many eyes cover a lot of search space. The space they have
to cover has grown immensely.

If you step off the trodden path you can find problems much more often. Just
recently I encountered a function in a run-time library that freed the amount
of memory the alloc asked for instead of the amount of memory the alloc
function actually returned (Sometimes it returned slightly more if the
remaining space was not enough to hold a free-memory structure).

It would not surprise me if the population using that particular
compiler/platform combination numbered less than a thousand.

------
lmilcin
I guess "it depends".

If you are beginner dev (I would say over 90% of all devs) or experienced but
never try to stress out your stack, it is not very likely that you are going
to encounter and properly recognize an error in your compiler. Even if you
encounter one, you will most likely change something until it starts to work
again and then you will shrug it off.

On the other hand if you are very experienced, you are routinely writing code
that stresses out your compiler (think algorithmic trading, etc.) and you are
in a habit of trying to get to the root cause of every failure, you are very
likely to find errors.

No non-trivial software is without bugs and compilers are some of the most
complex tools used in our job. Because they are very complex and heavily used,
all low-hanging bugs are already explored very well so what's left is
typically very complex and requiring expertise to recognize and debug.

------
allengeorge
Refuted by anecdote ;) In the first few months of working at my current job I
triggered three different bugs in the Scala compiler (2.10.x IIRC).

That said, I think most people - me included - don't reach for "compiler
error" until we've exhausted every other possibility.

~~~
raverbashing
Well, scala compilers are much less mature than C compilers

------
oldandtired
There are more compiler bugs than many ever think. From mainframe COBOL
compilers to gcc, I have encountered bugs in programs that were a result of
what the compiler did.

The original source code did nothing special - it was simple code and due to
specific optimisations that the compiler performed, inexplicable seemingly
random errors would arise. One would have to constrain the optimisations the
compiler would do to get the code to execute correctly.

No compiler is bug free. The bugs can manifest in strange ways and sometimes
they will manifest only on specific kinds of data (edge case data).

Certainly there are many programs that are written incorrectly and give rise
to apparently inexplicable errors that are due to misunderstood language
features or specified compiler limits.

However, there are also many programs that do not have such source code errors
that end up being rewritten in some way to avoid compiler based errors.

The worst I have seen is when dummy statements have to be put in to the source
code in order to get the program to work correctly. I have seen compilers
change the precision of numbers from one version to the next and you have to
add additional code to restrict those numbers back to the specified range. I
have seen compilers allocate multiple i/o buffers as an optimisation that
causes a program to fail when a single i/o buffer allocation works fine - one
has to turn off the optimisation - no documentation available as to how the
compiler generated code uses those buffers.

All I can say is that it takes a fair amount of investigation to determine
what kind of bug it is when it is subtle and randomly occurring. It can be
everything from errors in the source to errors in the libraries to errors in
code generation to errors in the o/s (including driver errors or memory
errors).

Anyone who blanket says the compiler is not to blame is living in a rose
coloured glasses world. Compilers are complex programs and the source code for
them can be just as wrong as for any other program. The code generated for
compilers can be just as bug ridden as any other program.

~~~
mark-r
C++ is notorious for exploiting what is technically undefined behavior to
produce unexplainable optimization bugs. Undefined behavior is extraordinarily
easy to write into your code without knowing it, and once it's there the
compiler is free to do any crazy thing it wants. You think it's a compiler bug
because turning off the optimizations fixes it, but it's not.

~~~
oldandtired
C++ (and its ilk) is a language that I don't touch with a 40 ft barge pole.
Irrespective of the aficionados of the language, it is poorly designed in oh
so many ways. I would rather program in BF, befunge, or remorse than C++.

------
harry8
List of times we've seen the loch ness monster here? Fun!

gcc's __attribute__(aligned(N))

Whenever you see it if you assume it doesn't do what you think it does from
reading the docs that's probably a sound strategy.[1][2]

I'd love it if I'm wrong and there is a way of understanding what it is meant
to do and successfully predicting behavior.

[1]
[https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82914](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82914)
[2]
[https://gcc.gnu.org/ml/gcc/2014-06/msg00308.html](https://gcc.gnu.org/ml/gcc/2014-06/msg00308.html)

~~~
ghewgill
GCC isn't the only one with aligned() bugs:
[https://bugs.llvm.org/show_bug.cgi?id=23868](https://bugs.llvm.org/show_bug.cgi?id=23868)

Over two years and no forward progress! Admittedly, I haven't re-tested this
with a newer compiler. But apparently neither has anybody else.

------
mtm
I was a user of a very early version of Zortech C++ (one of the first native
C++ compilers (late '80s); no running through cfront) and ran into a very
subtle bug in the math routines: sometimes when doing math with 8 bit values
the answers would be corrupted. Took a while for me to track down the bug but
I eventually found it in the assembly output. Turns out that the math was
actually being done with 16 bit registers and the high byte (AH) was not being
cleared and this would sometimes set a carry (I think, my memory is fuzzy on
the details).

Walter was quick with a fix. Sometimes it is the compiler, but usually it's
not.

~~~
mark-r
I was using a cross compiler for the 68000 around the same time period, and we
ran into many compiler bugs. They were always quick to fix them once we could
produce a small example program to demonstrate the problem, but it was a bit
frustrating. Thankfully it has been many years since I ran into a true
compiler bug.

------
AceJohnny2
I work in embedded software, usually with compilers co-evolving with the
hardware.

In 10 years, I've seen 3 compiler bugs. That's just enough to leave the door
cracked open for "y'know, it _could_ be a compiler bug..."

------
jejones3141
I used to work on a compiler--and it is sometimes a compiler error. I have to
admit, though, that it was a pleasure to reply to a bug report with "If you
close this comment here, you will get the result you expected."

------
mar77i
The article actually speaks reason.

As somebody who learned C in a way that over time made me aware of the whole
"compiler bug" vs. "the standard said so" thing, I'm still not over the
nightmare that was "Admitting Defeat On K&R in LCTHW"... Beneath is the link,
be warned that this read is probably not for the light hearted.

[https://zedshaw.com/2015/01/04/admitting-defeat-on-kr-in-
lct...](https://zedshaw.com/2015/01/04/admitting-defeat-on-kr-in-lcthw/)

------
ythn
I've run into tons of compiler errors, especially compilers generated by Yocto
project. I've also had weird behavior from compilers when running in a VM.

For example: [https://stackoverflow.com/questions/45424272/gnu-gcc-bug-
whe...](https://stackoverflow.com/questions/45424272/gnu-gcc-bug-when-using-
both-sysroot-and-c11)

------
glangdale
We've found compiler errors frequently. An absolute hot-spot for compiler
errors for us was (relatively) obscure platforms, so we found SDKs for
embedded MIPS processors that broke basic gcc intrinsics. No-one had ever
noticed that really basic intrinsics (at the level of popcount/count leading
zeros) were wrong.

C++ was another hotspot of brokenness for early gcc 4.x.

------
PinguTS
Sometime it is a compiler bug and sometimes the linker even can correct it.

We had this weird behavior some years ago in an embedded functional safety-
related project where a case tool generated the code for the compiler.

When the generated code looked like this:

    
    
      i++;
      i++;
      i++;
      i++;
      i++;
      if (i > something) {
      } else {
      }
    

Then the compiler was miscalculating the jump by 2 bytes in the _else_ path.

But if the generated code was this (spot the difference):

    
    
      i++;
      i++;
      i++;
      i++;
      if (i > something) {
      } else {
      }
    

The compiler correctly calculated the jumps. If certain optimization option
was enabled, the linker afterwards corrected the miscalculated jump.

The compiler vendor could reproduce the behavior aka bug, but could not say
with confidence the circumstaalnce what the cause for this bug was. As it was
for a function safety-related product we where required to identify all jumps
caused by _if_ clauses and had to review the assembly, if the jumps in the
assembly were correct.

------
js2
Recall that TimSort had an undiagnosed bug for over a decade:

[http://envisage-project.eu/proving-android-java-and-
python-s...](http://envisage-project.eu/proving-android-java-and-python-
sorting-algorithm-is-broken-and-how-to-fix-it/)

------
tormeh
I remember using g++ on Windows (via cygwin or something) and writing a
function that was supposed to return a Boolean, but sometimes didn't return
any value at all. Real spaghetti, in university, no less. Throwaway code, in
my defense. Turns out the code not only escaped detection, but the resulting
binary always returned the same Boolean value when the code path where no
return should be made were run.

Don't think I've seen one since, though I have found a nasty footgun in Scala
where if you do a fold of a parallel collection, you can give the fold a
starting value, which will be supplied to all the executing threads. The
result therefore depends on how many cores you have running. Sadly I suspect
that one's in spec.

------
TheAceOfHearts
I work as a frontend engineer and used to think similarly. I don't think I
encountered any browser bugs for the first few years, as I was mostly just
wiring stuff up and wasn't taking advantage of newer APIs. But eventually I
started trying out newer APIs, and I would occasionally bump into weird and
unexpected behavior. I was always convinced it was my own fault, but after
countless hours trying to debug why something was behaving oddly, I'd look up
a few keywords and usually found bug reports in each browser's issue tracker.

Browsers are incredibly complex pieces of software which are constantly
evolving. Go look at any browser's issue tracker and you'll find a huge list
of bugs.

------
krallja
“The Pragmatic Programmer” refers to this idea as “select() is broken.”

~~~
rkachowski
it's a small typo but changes the meaning completely, it's - Select _"isn't"_
broken

~~~
krallja
You are right that the other way is more prominent, but both phrases appear in
the book; for example,

“We now use the phrase "select is broken" as a gentle reminder whenever one of
us starts blaming the system for a fault that is likely to be our own.”

That quote appears right above «Tip 26: “select” isn’t broken.»

------
IncRnd
Well, a couple years ago I encountered compiler bugs with Zortech C, after it
was purchased by Symantec. Zortech C was a great compiler, but that quality
fell down in the version released version from Symantec. The code didn't
change but the compiler did. Some code no longer compiled by the new compiler
and other code would crash at runtime. This was simple code, but there was
something about how the compiler handled private structs or public classes
that caused these issues.

------
conistonwater
How did that bug pass testing? Isn't the first test of correctness that you
generate the 3.5 million permutations of 1..10 and sort every single one
correctly?

------
Macha
When I first started using Jenkins Workflow, I ran into tons of these with
their Groovy interpreter, even for basic stuff such as Map#each.

Of course, that was pre-1.0 software..

------
dbrgn
It depends a bit on the age of the compiler. I hit a strange bug in
Micropython back when it was still pretty new, that would lead to 0 != 0:

[https://github.com/micropython/micropython/issues/610](https://github.com/micropython/micropython/issues/610)

In the end it was a buggy implementation of the & operator on long integers,
which was fixed very quickly.

------
csours
In userland, if some fraction of the user base misuses a feature, that could
be considered a bug, even if it is working as designed.

Obviously things like forward and backward compatibility are much more
important in the programming context, so you can't just "fix" things like
weird side effects or not throwing an error on assignment in an if statement.

------
dredmorbius
In over a quarter century of programming, I've twice found interpreter errors.
Once a function performed the inverse of the documented behaviour (returning
"true" for "false" and vice versa) in a proprietary system, the second was a
gawk bug of some description I don't recall but proved to be an actual bug.

The other bugs were all mine.

~~~
pm215
That first one reminded me of the gripe at the top of perl's Configure script
[https://perl5.git.perl.org/perl.git/blob/HEAD:/Configure#l36](https://perl5.git.perl.org/perl.git/blob/HEAD:/Configure#l36)
\-- "SCO csh still thinks true is false. Write to SCO today and tell them that
next year Configure ought to "rm /bin/csh" unless they fix their blasted
shell. :-)"

which only gets printed if the shell it's running in egregiously mishandles
&&...

~~~
kpil
I think someone did a rm -f on SCO, so the problem is solved.

~~~
dredmorbius
The court case is, of late October 2017, still alive, believe it or not.

------
bitwize
I came across a bug in the JDK/JRE 1.0.1 relating to GridBagLayouts. Sometimes
they would just ignore the directives the programmer specified and lay things
out any damn place they liked. I only reported it after checking and
rechecking and rechecking that I had use the GridBagLayout API exactly
according to the documentation.

It was fixed in Java 1.0.3.

~~~
amichal
GridBagLayout was the worst back then. It almost got banned in my office and
we had several views with gross manual implementations of it because whatever
we wanted to do triggered insanity and writing the few constraints see wanted
to work procedurally was way easier

------
eric_the_read
Way back in the day HP had just transitioned its HP-UX C++ compiler from its
older, Cfront-based, C++ compiler to a native solution. I found (in released
code, no less!) some fairly trivial template compositions (I forget exactly,
but it was something like a map of some object to a vector of something else)
that crashed the compiler.

------
PeterStuer
Depends on the context. Most people's only exposure has been to widely used or
open source based compilers. I remember working with proprietary cross
compilers for micro-controllers in the 90's. In that environment 'compiler
errors' where not that uncommon at all.

------
null000
Depends on the language. Never encountered a C++ or C compiler bug, but I've
hit 2 separate & nasty Python runtime environment bugs (one that caused a
segfault because of some memory trampling from having too many file
descriptors open, and one edge-case sorting bug).

------
keithnoizu
You gotta through a lot of those sort of expectations out of the windows when
working with js. . . imho

~~~
mottomotto
It is silly to kick JavaScript in this example because the bug* is in the
library of a custom JavaScript interpreter not a common runtime.

* [https://github.com/code-dot-org/JS-Interpreter/pull/23](https://github.com/code-dot-org/JS-Interpreter/pull/23)

~~~
harry8
We should consider separate bugs in the language spec from the implementation.
In JS it's insane not to K&R brace as it will try to infer missing semi-colon
terminators in your code, silently, to your doom. That's surprising if you
have the misfortune. It's a massive bug in the language spec but the
implementation of the JS interpreter is 100% correct as it kicks you, hard.

Parent comment makes sense to me as a general comment about getting good at
JS. Especially given JS has so many new and exciting libraries that get used
in production. Ultimately you must fix your code, JS & libraries aren't likely
to change in a timely fashion. And of course what I call a bug in the spec
must have been considered a feature at one time, some may still consider it
so. That's a question of taste and you can always consider yourself 100%
correct on any matter of taste simultaneously with those who disagree. :-)

~~~
inimino
K&R braces have approximately nothing to do with semicolon insertion...

~~~
krallja
Compare the values of these function bodies:

    
    
        return {
        };
    

and

    
    
        return
        {
        };

~~~
inimino
Yes, those are different, but K&R brace is a style of where you put the braces
in a function body or a block. The braces in your example are creating an
object literal.

The K&R brace style is not about putting an object literal on the same line
with a return statement or on another line, but about how control structures
are formatted.

The reason I said that K&R brace style has nothing to do with semicolon
insertion is that it’s possible to write all your control structures with K&R
braces and still be bitten by the places in the grammar where line breaks are
not allowed, like after a return statement, if you’re unaware of it.

It’s also possible to use Allman braces everywhere and never have that problem
with return statements.

------
EpicEng
I fixed a bug (random crash) about eight years ago now caused by the Intel
compiler failing to properly copy a function parameter into a register. At
some point I just gave up looking at the code and took a peak at the
disassembly. There it was.

So yeah, it's sometimes a compiler error.

------
IndrekR
I have discovered two compiler bugs that got fixed after reporting them. In
both cases it was relatively new implementation at the time (TI C55x in CCS
and TI MSP430 in IAR). In both cases the compiler generated wrong assembly
code. This almost never happens. Almost.

------
wcarss
I recently learned of a pretty surprising chrome console interpreter bug that
was reported as early as 2010[1], fixed by 2012, and at some point seems to
have degraded again.

console.log lazily evaluates complex values at first-expand-time, rather than
eagerly at print-time, and there is no built-in facility to automatically
expand them at print-time. To see this being weird, try logging a changing
array inside of a loop, then expand the first log after the loop completes. It
will show the array state at click-time, rather than at the point in time the
log statement executed. Subsequent changes to the array will not be reflected.

People have been complaining for years about this, but it seems to be widely
accepted as just-the-way-it-is[2-4], with the most common workaround being
JSON.stringifying logged objects.

I'm mostly shocked that I only noticed I was being bit by it a little while
ago.

1 - (2010, shows 2012 fix)
[https://bugs.webkit.org/show_bug.cgi?id=35801](https://bugs.webkit.org/show_bug.cgi?id=35801)

2 - (2010, w/ edits to note 2012 fix)
[https://stackoverflow.com/questions/4057440/is-chromes-
javas...](https://stackoverflow.com/questions/4057440/is-chromes-javascript-
console-lazy-about-evaluating-arrays)

3 - (2014) [https://stackoverflow.com/questions/23392111/console-log-
asy...](https://stackoverflow.com/questions/23392111/console-log-async-or-
sync)

4 - (2016) [https://taoalpha.github.io/blog/2016/04/21/tech-lazy-
evaluat...](https://taoalpha.github.io/blog/2016/04/21/tech-lazy-evaluation-
of-console-log/)

------
pjmlp
I found out one in Turbo Pascal for MS-DOS.

Pascal functions use assignment to function name as the way to set the return
value, as it happens, Turbo Pascal would allow declaring a local variable with
the same name and then return garbage as the function's result.

------
ghelmer
A summer spent testing (and breaking) compilers taught me a lot, including:
compilers do have obscure bugs. 99.99999% of program errors are bugs in the
code, but the rare compiler bug is maddening to diagnose.

------
finnh
Nice use of the "House of Leaves" technique for heightening dramatic tension
in the face of saccades.

    
    
      was sorting the numbers
    
      into
    
      the
    
      wrong
    
      order.

------
hyperpallium
[https://youtube.com/watch?v=k4RRi_ntQc8&t=0m49s](https://youtube.com/watch?v=k4RRi_ntQc8&t=0m49s)

------
supermatt
It definitely depends on the maturity (and volume of usage) of the compiler.
I'm pretty sure i could write a compiler that was full of bugs ;)

------
lowbloodsugar
<pedantry>A bug in sort doesn't sort like a compiler error. Sounds like a bug
in the standard library.</pedantry>

------
rurban
The perl5 if statement is still broken after >30 years btw. It still is a
compiler error, but a subtle one in very rare occasions.

------
dclowd9901
I don't understand the env in which this happened, because cracking open my
console, I get

> [5, 4, 5, 1].sort().join('')

> "1455"

~~~
jontro
They are using a sandboxed javascript interpreter. [https://github.com/code-
dot-org/JS-Interpreter](https://github.com/code-dot-org/JS-Interpreter)

See the pull request here [https://github.com/code-dot-org/JS-
Interpreter/pull/23](https://github.com/code-dot-org/JS-Interpreter/pull/23)

~~~
jandrese
Basically, the chance that it is a compiler bug is proportional to the inverse
of the number of people using it. You probably didn't find a bug in gcc. It's
definitely possible that you found a bug in some bespoke javascript
interpreter that few people have ever even heard of.

------
clhodapp
Eh, I feel like I manage to find something to crash scalac about every month
or two.

------
aspyct
Compiler errors are a daily issue with Xamarin unfortunately...

------
pdkl95
re: the fix for the off-by-one error

    
    
        // but it should have been: 
        if (changes == 0) break;
    

While this fixes the problem, it no longer handles the case where count is
negative. Yes, in this function it's likely that "this never happens", but
it's generally good practice assume as little as possible.

    
    
        // still stops on negative values
        if (changes < 1) break;
    

or if negative values could indicate some kind of serious problem:

    
    
        // first trap problems
        if (changes < 0) raise_error();
        if (changes == 0) break;

~~~
krallja
A negative number of changes is nonsensical, so the programmer doesn’t need to
defend against it.

~~~
pdkl95
> A negative number of changes is nonsensical

Of course. As I said, I know this is defending as case that _shouldn 't_
happen.

> the programmer doesn’t need to defend against it

My point is that this is a dangerous attitude that can create bugs. A less-
than comparison should cost the same as testing for quality, so _only_ testing
for 0 isn't faster.

Why are negative values nonsensical? Is is because the variable is _named_
changes? The algorithm in the preceding code? Comments in the code near that
variable? All of these things can change as code evolves. Variables are
repurposed, algorithms change (sometimes radically), and updates to code can
desynchronize from comments.

~~~
krallja
If there are a negative number of changes in bubble sort, why is returning
early any more valid than continuing with the loop? Think about how bubble
sort should work. There is no correct next step to take if count is negative.
A negative count of changes is nonsensical. The only option that I could agree
with, if you’re going to bother coding anything in this case, is to terminate
execution, because the program is incorrect.

~~~
pdkl95
> why is returning early any more valid than continuing with the loop?

You could consider it an extension of the "0" condition. However...

> terminate execution, because the program is incorrect.

...this is probably better than simply terminating the loop.

------
adekok
I ran into a GCC bug years ago. (1999-2000). It would put "static" variables
into the "text" section of ELF binaries.

i.e. into the _read-only_ portion of the binary.

The result, of course, was that _writing_ to the variables caused a core dump.

So yes, 99% of the time, stupid programmer errors are stupid programmer
errors. But compilers _do_ have bugs.

e.g.

[https://github.com/practicalswift/swift-compiler-
crashes](https://github.com/practicalswift/swift-compiler-crashes)

~~~
yaur
Im going to guess that was 2.96

[https://www.gnu.org/software/gcc/gcc-2.96.html](https://www.gnu.org/software/gcc/gcc-2.96.html)

------
PeachPlum
> Here's something I wrote in October 2000

I hope Mark Dominus has learned how not to use sarcasm and condescension in
his coaching style since then. Toxic environments kill people.

~~~
gnclmorais
You definitely don’t know Mark. He is a great, friendly person I had the
pleasure to meet a couple of years ago. Hi Mark!

------
muxator
Yes, it's always your fault.

------
erikbye
Eh, no, never. The article is bullshit.

[https://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=__open__...](https://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=__open__&no_redirect=1&order=Importance&query_format=specific)

[https://bugs.llvm.org/buglist.cgi?bug_status=__open__&no_red...](https://bugs.llvm.org/buglist.cgi?bug_status=__open__&no_redirect=1&order=Importance&query_format=specific)

I fight compiler bugs all the time. Poor optimizations, poor comparisons, bad
allocations, incorrect warnings and errors, long compile times due to bugs,
don't even get me started on GCC intrinsics and SIMD.

