49
\$\begingroup\$

The challenge:

Write a very short program that, when compiled, creates the most amount of compiler warnings and errors. It can be written in any programming language.

Scoring:

The score is determined by this equation: errors_and_warnings_length/code_length. Highest score wins.

Example:

The C# program class is 5 chars long and generates 3 warnings, which is a score of (1/5)*3 = 0.6.

EDIT:

Because of some confusion, programs have to be at least 1 char long. Otherwise it would get a score of infinity.

\$\endgroup\$
6
  • 19
    \$\begingroup\$ While I like the concept, I find the metric a little worrisome. What compiler? What settings (especially with regard to warnings)? I mean gcc -Wall -pedantic is very different from plain ol` gcc is different from tcc is presumably different from some other c compiler. \$\endgroup\$ May 12, 2012 at 16:18
  • 4
    \$\begingroup\$ Just get a compiler in Russian, or German, you get some LONG errors(no pun intended) \$\endgroup\$
    – nanofarad
    May 13, 2012 at 0:02
  • 3
    \$\begingroup\$ I'd love to see answers in languages other than C/C++. \$\endgroup\$
    – Ken Bloom
    May 13, 2012 at 14:10
  • 5
    \$\begingroup\$ I would've liked it if the challenge was to generate as many different errors as possible \$\endgroup\$
    – Hannesh
    May 24, 2012 at 14:48
  • 3
    \$\begingroup\$ Ahem. Otherwise its score would be undefined. \$\endgroup\$
    – wizzwizz4
    Apr 28, 2016 at 17:20

10 Answers 10

99
\$\begingroup\$

GCC, score 2200 / 36 ≈ 4.5 × 1058

#include __FILE__
#include __FILE__

I have not actually finished compiling this code, but based on testing and simple mathematics, it should produce a total of 2200 #include nested too deeply errors.

Of course, the program is trivially extensible. Adding a third line brings the score up to 3200 / 54 ≈ 4.9 × 1093. Four lines give 4200 / 72 ≈ 3.6 × 10118, and so on.

\$\endgroup\$
8
  • 7
    \$\begingroup\$ Very clever answer. +1 \$\endgroup\$ May 12, 2012 at 16:59
  • 6
    \$\begingroup\$ Very clever I agree, but I'd count that as 1 error ("nested too deeply"), not a separate error for each line of the backtrace. \$\endgroup\$
    – Kevin
    May 13, 2012 at 2:20
  • 1
    \$\begingroup\$ @Kevin: Just to be clear, it should produce that error 2²⁰⁰ times, once for each possible path by which the nesting limit can be reached. The fact that each error also includes 200 lines of backtrace just makes the output even more verbose. \$\endgroup\$ May 13, 2012 at 11:29
  • 2
    \$\begingroup\$ Hmm. I could swear when I tried it last night gcc bailed after 1 error, but it appears to be running printing more now. Objection withdrawn. Incidentally, is 200 from the c standard? \$\endgroup\$
    – Kevin
    May 13, 2012 at 13:42
  • 1
    \$\begingroup\$ @Kevin Per gcc.gnu.org/onlinedocs/gcc-4.8.2/cpp/Implementation-limits.html : "We impose an arbitrary limit of 200 levels [of nested #include], to avoid runaway recursion. The standard requires at least 15 levels." \$\endgroup\$
    – zwol
    Jan 7, 2014 at 15:12
53
\$\begingroup\$

C, 0 characters - Score=(1/0)*1=Infinity


generates 1 error:

/usr/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status

Note: http://ideone.com/xdoJyA

\$\endgroup\$
16
  • 50
    \$\begingroup\$ 1/0 is undefined, not "infinity". \$\endgroup\$
    – Frank
    May 12, 2012 at 16:23
  • 3
    \$\begingroup\$ +1 Even if 1/0 is undefined, it's demonstrably larger than one divided by any larger number. 0 takes the cake. \$\endgroup\$
    – jnm2
    May 12, 2012 at 17:41
  • 7
    \$\begingroup\$ @jnm2 not sure about that. 1/0 is undefined and, although right side approaches +infinity, that doesn't make 1/0 defined at all. \$\endgroup\$
    – kaoD
    May 12, 2012 at 17:52
  • 6
    \$\begingroup\$ Since the domain is positive, I think what I said makes sense. Theory is fun but I think we need some common sense here. The most compiler errors for the least amount of code, remember. The limit is obvious. \$\endgroup\$
    – jnm2
    May 12, 2012 at 19:56
  • 19
    \$\begingroup\$ 1.0/0.0 = +INF, at least according to IEEE 754 :) So you just have to do the calculation in floating point. \$\endgroup\$ May 12, 2012 at 21:07
20
\$\begingroup\$

GCC, score 5586.6 (and more if needed)

179 chars, 1000003 warnings/errors (using -Wall)

#define E a,a,a,a,a,a,a,a,a,a
#define D E,E,E,E,E,E,E,E,E,E
#define C D,D,D,D,D,D,D,D,D,D
#define B C,C,C,C,C,C,C,C,C,C
#define A B,B,B,B,B,B,B,B,B,B
_(){A,A,A,A,A,A,A,A,A,A}

This can be extended arbitrarily, of course. For example, using 10 #defines instead of 5 and a length of 20 "calls" instead of 10 would lead to a score of about (20**10)/(179*4) = 14301675977.65 (and would take quite some time to run ;)

\$\endgroup\$
2
  • 8
    \$\begingroup\$ Using #define X(A) A,A,A,A,A,A,A and X(X(X(X(X(X(A)))))) you can duplicate code much faster. \$\endgroup\$
    – ugoren
    May 13, 2012 at 6:56
  • \$\begingroup\$ An application of the billion laughs attack, nice. \$\endgroup\$
    – Caesar
    Jun 18 at 13:35
13
\$\begingroup\$

GCC twice, 86

22 chars, 1898 errors+warnings on my system.
I'm sure this approach can be much improved, by choosing longer files with shorter names.

#include</usr/bin/gcc>
\$\endgroup\$
1
  • 5
    \$\begingroup\$ /usr/bin/gdb is significantly larger (5.5M vs 760K), but /vmlinuz at 5.6M might be your best bet. \$\endgroup\$
    – wchargin
    Mar 5, 2015 at 3:59
12
\$\begingroup\$

HQ9++, 1 (limit of (n+29)/n)

The following emits the warning Warning: this is not a quine for each Q in the code.

QQQQQ...Q
Warning: this is not a quine

Small is good, right? Hmm...

\$\endgroup\$
1
  • \$\begingroup\$ FWIW, this is a joke. If that wasn't obvious. \$\endgroup\$
    – boothby
    May 29, 2012 at 16:11
10
\$\begingroup\$

C, .727

11 chars, 5 errors, 3 warnings, (1/11)*8 = .727273

m(;){@,x}2

cc -g -Wall    er.c   -o er
er.c:1: error: expected declaration specifiers or '...' before ';' token
er.c:1: warning: return type defaults to 'int'
er.c: In function 'm':
er.c:1: error: stray '@' in program
er.c:1: error: expected expression before ',' token
er.c:1: error: 'x' undeclared (first use in this function)
er.c:1: error: (Each undeclared identifier is reported only once
er.c:1: error: for each function it appears in.)
er.c:1: warning: left-hand operand of comma expression has no effect
er.c:1: warning: control reaches end of non-void function
er.c: At top level:
er.c:1: error: expected identifier or '(' before numeric constant

\$\endgroup\$
4
  • \$\begingroup\$ I count 5 errors, plus 3 warnings \$\endgroup\$
    – Kevin
    May 13, 2012 at 2:15
  • \$\begingroup\$ I suppose you're right. I was counting the "error:" and "warning:" strings. \$\endgroup\$ May 13, 2012 at 2:30
  • 5
    \$\begingroup\$ I think you win if we only count different errors/warnings. \$\endgroup\$
    – ugoren
    May 13, 2012 at 7:03
  • \$\begingroup\$ If -Werror is used on the command line, warnings are promoted to errors. And also, which C compiler used will affect the number of reported errors (or if -Werror is available, etc.) One might argue the command line length for invocation might be counted as part of the "program" length... and each compiler version on each platform is a separate category. :-) \$\endgroup\$ Apr 3, 2018 at 0:21
8
\$\begingroup\$

NASM, score 63/40 * 2^32 ≈ 2.905 * 10^19

%rep 1<<32
%rep 1<<32
!
%endrep
%endrep

Will output c.asm:3: error: label or instruction expected at start of line 2^64 times. Again this is easily extensible to much bigger outputs.

\$\endgroup\$
3
\$\begingroup\$

C++98 (211 bytes) g++-5 (Ubuntu 5.2.1-23ubuntu1~12.04) 5.2.1 0151031

I wanted to see how well I could do in C++ without using the preprocessor at all. This program produces 2,139,390,572 bytes of output, most of which is a single error message.

template<int i,class S,class T>struct R{typedef R<i,typename R<i-1,S,S>::D,typename R<i-1,S,S>::D>D;};template<class S,class T>struct R<0,S,T>{typedef S D;};void f(){R<27,float,R<24,int*const*,int>::D>::D&E=4;}

me@Basement:~/src/junk$ ls -l a.C
-rw-rw-r-- 1 me me 211 Apr 27 21:44 a.C
me@Basement:~/src/junk$ g++-5 a.C -fmax-errors=1 2>a.C.errors.txt
me@Basement:~/src/junk$ ls -l a.C.errors.txt 
-rw-rw-r-- 1 me me 2139390572 Apr 27 22:01 a.C.errors.txt

Ungolfed:

template <int i, class S, class T>
struct R {
    typedef R<i, typename R<i-1,S,S>::D, typename R<i-1,S,S>::D> D;
};
template <class S, class T>
struct R<0, S, T> {
    typedef S D;
};
void f() {
    R<27, float, R<24, int*const*, int>::D>::D &E = 4;
}

This program works by defining a recursive struct template R which holds a typedef D containing two copies of R. This results in an type name which grows exponentially, which is printed out in full in the error message. Unfortunately, g++ seems to choke while attempting to print an error message longer than (1<<31) bytes. 2,139,390,572 bytes was the closest I could get to the limit without going over. I'm curious if anyone can adjust the recursion limits and parameter types 27, float, 24, int*const* to get closer to the limit (or find a compiler which can print an even longer error message).

Excerpts from the error message:

a.C: In function ‘void f()’:
a.C:1:208:  error:  invalid  initialization  of non-const reference of type
‘R<27, float, R<24, R<23, R<22, R<21, R<20, R<19, R<18, R<17, R<16, R<15,
R<14,  R<13, R<12, R<11, R<10, R<9, R<8, R<7, R<6, R<5, R<4, R<3, R<2, R<1,
int* const*, int* const*>, R<1, int* const*, int* const*> >, R<2, R<1, int*
const*,  int*  const*>,  R<1, int* const*, int* const*> > >, R<3, R<2, R<1,
int* const*, int* const*>, R<1, int* const*, int* const*> >, R<2, R<1, int*
const*,  int* const*>, R<1, int* const*, int* const*> > > >, R<4, R<3, R<2,
R<1, int* const*, int* const*>, R<1,
...
int*  const*,  int*  const*>  > > > > > > > > > > > > > > > > > > > > > > >
>::D& {aka R<27, R<26, R<25, R<24, R<23,  R<22,  R<21,  R<20,  R<19,  R<18,
R<17,  R<16,  R<15,  R<14, R<13, R<12, R<11, R<10, R<9, R<8, R<7, R<6, R<5,
R<4, R<3, R<2, R<1, float, float>, R<1, float, float> >, R<2,  R<1,  float,
float>,  R<1,  float, float> > >, R<3, R<2, R<1, float, float>, R<1, float,
float> >, R<2, R<1, float, float>, R<1, float, float> > > >, R<4, 
...
, R<1, float, float>, R<1, float, float> > >, R<3, R<2, R<1, float, float>,
R<1, float, float> >, R<2, R<1, float, float>, R<1, float, float> > > > > >
>  >  >  >  >  >  > > > > > > > > > > > > > > >&}’ from an rvalue of type
‘int’
    template<int    i,class   S,class   T>struct   R{typedef   R<i,typename
R<i-1,S,S>::D,typename  R<i-1,S,S>::D>D;};template<class  S,class  T>struct
R<0,S,T>{typedef                         S                         D;};void
f(){R<27,float,R<24,int*const*,int>::D>::D&E=4;}


                                                        ^
compilation terminated due to -fmax-errors=1.

2,139,390,572 bytes / 211 bytes = 10,139,291.8

\$\endgroup\$
2
  • \$\begingroup\$ This is why I always use STLfilt... Welcome to PPCG! This is a great first submission! \$\endgroup\$
    – user45941
    Apr 28, 2016 at 6:10
  • 3
    \$\begingroup\$ Unfortunately it seems I misunderstood the challenge; it seems submissions are scored by the number of error messages, not the byte count. Obviously my 1 error entry is not very competitive. Perhaps my answer should be moved here \$\endgroup\$ Apr 28, 2016 at 8:00
2
\$\begingroup\$

SmileBASIC, 1/1 = 1

A

Generates the error Syntax Error in 0:1

\$\endgroup\$
1
  • \$\begingroup\$ SB only ever generates one error at a time, so this is really the only answer you can make. \$\endgroup\$
    – snail_
    Feb 3, 2017 at 4:33
2
\$\begingroup\$

Rust, 206 chars, 220+2 errors, score 5090, tunable.

macro_rules! e {
    ($e:expr, $($es:expr),+) => {
    compile_error!(stringify!($e, $($es),+));
        e! { $(a + $es),+ }
        e! { $(b + $es),+ }
    };
}
e! {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}

And you can actually see it finish compilation, in about 3 minutes for me:

error: could not compile `a` due to 1048578 previous errors

Like the C #include __FILE__ example above, it is tunable, but

  • if you want to go beyond 2256, you need to set #![recursion_limit = "9999999"]
  • rustc will OOM long before you can reach that
  • longer expressions mean slower execution, so the more errors you want, the slower they will be printed

What I actually wanted to do is implement the Péter's variant of the Ackermann function. But I don't quite grok macros well enough to do that with the unary encoding. Anyone help?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy