Files
ioccc/bugs.md
T
Cody Boone Ferguson b5dc413e57 Undo two segfault fixes in 1991/dds - INABIAF
I noticed that I unfortunately fixed two segfaults that should not have
been fixed: if the input file cannot be opened for reading or the output
file cannot be opened for writing this program will crash. Changed both
dds.c and dds.alt.c (which I added to work with clang). The original fix
that allows this entry to work at all (segfaulted always) remains in
both versions.

Updated README.md and bugs.md. In bugs.md I also added a note that the
compiled code uses gets() not fgets() - whatever it might be worth.
2023-04-13 05:01:38 -07:00

45 KiB

BUGS and (MIS)FEATURES

There are a number of known problems with IOCCC winners: many of which have to do with differences between today's compiler environments and those of today. In some cases the original code has a bug, some of which were recently discovered and many of which were fixed. In some cases attempt to port older code to more modern environments introduced bugs.

The following is a known list of BUGS and (mis)FEATURES in IOCCC winners.

Can you fix/improve entries not under the INABIAF (it's not a bug it's a feature)? You are VERY WELCOME to try.

Please submit your fixes in a GitHub pull request (with ONE PULL REQUEST PER FIX, please)!

We will be happy to credit anyone who submits successful GitHub pull requests in the entry's README.md file. If you're a previous winner we will add a link to your winning entries in the file (if you're not a previous winner we can add a link to your GitHub page or personal website if you have one, should you wish).

If you do fix an entry please feel free to delete the entry from this file! Otherwise if you wish to not worry about it we can do that to make sure the format is consistent and clean.

THANK YOU!

To the winning authors:

If you're the author of an entry that has been fixed and you find it against your liking PLEASE let us know and we'll be happy to undo any fixes even if it takes away some instructional value or even usability. In this case we're **VERY SORRY** about it: it's a fine line, we know, and we tried to use careful judgement but invariably some might have been the wrong decision. Thank you for understanding!

ON ALL FIXES / IMPROVEMENTS / CHANGES

Make ABSOLUTE CERTAIN that you test the entry BEFORE AND AFTER your changes! This includes output and the same input functionality! Sometimes it might seem to be fine but is actually not! We will note some where this is known to happen (if it's not yet fixed). This has actually already happened to us. Sometimes it is okay: some entries are known to not work but they can still have improvements (rarer situation but it's happened). Some might have slightly different output but which is not a problem for instance a newline after output in Cody Boone Ferguson's changing it to 1994/ldb use fgets() from gets().

Make ABSOLUTE CERTAIN that you read the README.md file BEFORE your changes as it's important to see that the code is doing what it is supposed to. In the case that it's not obvious (some README.md files do not even have commands to try or even explain how to use it!) then you should either skip the entry OR ask someone who will know e.g. us.

Make ABSOLUTE CERTAIN that you read the next section, the list of statuses and the related information, BEFORE you submit a pull request!

BE VERY AWARE that sometimes fixing an entry for one platform will break it under another so if you have more than one platform (e.g. macOS and linux) it would be wise to test it under all that you have access to. Otherwise we can do that. Of course if the entry does not work under any platform and you fix it for one that's more than fine (and it has been done numerous times).

Again, THANK YOU!

LIST OF STATUSES - PLEASE READ BEFORE FIXING (you may skip if you're only interested in knowing about entries with known issues)

Entries below have one or more of the following STATUS values. Please see the text below for more information. If an entry has more than one status it means that either they all apply or they compliment each other. For instance 2004/gavin crashes but it also doesn't even compile with some platforms/architectures.

Cody Boone Ferguson has been working on resolving these issues and has fixed many but you're welcome to have a go at it too (though he'll be very sad if he doesn't have a chance to at first fix it :-( so you might want to hold off for now :-) .. or not :-) ). He hopes to have most of the remaining entries resolved in the near future but nevertheless if you're okay making people very sad you may have a go at the entries :-) He'll remove this part later on.

General notes about the statuses and making fixes

Compiler warnings are very rarely a problem

In general warnings should NOT be addressed. The only time they should be CONSIDERED is when the entry does not work. However note that sometimes trying to fix the warnings will actually introduce bugs! Other times 'fixing' them will break the entry (see below).

Below in some entries we do list some warnings that definitely should be ignored (including some introduced by fixes) but we do not list them all: trying to keep track of them all would be impractical especially as different compilers give different warnings.

Another type of warning that would be hard to keep track of is different data sizes on different platforms. These tend to be required at the risk that sometimes the entry will not work for certain platforms, some of which might or might not be fixable; a good example where it was required to change and is okay is when Cody Boone Ferguson fixed the segfault in macOS of 1989/paul: changing the int * to a long * was required and it works just as well with linux.

But even if they are fixable (which will likely be hard to do) it's almost certain that such code would be just as non-portable (importable ? :-) ).

Hopefully with the example entries listed above you get the idea.

Request for one-liners:

For one-liners please keep the file one line if at all possible! If it needs an include you can update the Makefile CINCLUDE variable. For instance if it needs stdio.h you could do -include stdio.h. Please leave a space after the = in the Makefile and thank you!

On layout of program source

If you make changes PLEASE TRY and keep the source code layout as close to the original as possible. This might not always be possible and if you have an editor that does formatting it can cause problems. Sometimes formatters can even break code! Cody Boone Ferguson has experienced this many times with vim so he tends to disable all format options when formatting code.

STATUS: known bug - please help us fix

Entries with this status have one or more bugs that need to be fixed. Are you able to fix it? We welcome your help!

An important point to note is that there is a very fine line when fixing bugs where it might sometimes border on tampering with the program. And after all, these are not meant to be maintainable or even good programming style! Use careful judgement when fixing bugs please!

STATUS: possible bug (possibly depending on system) - please help test and if necessary fix

Entries with this status might or might not have a bug possibly depending on the system. In these entries we don't have the appropriate systems to test and fix any problems.

STATUS: doesn't work with some platforms - please help us fix

Entries with this status do not work under some OSes and/or architectures (and/or something else?). Please help us to fix it!

STATUS: doesn't work with some compilers - please provide alternative code

Some entries do not work with some compilers. A good example is 1992/lush which uses error messages from the compiler to generate its output.

Please help us by writing alternative code!

STATUS: main() function args not allowed - please help us fix

Entries with this status have a problem in that the args to main() are not of a specific type due this being allowed in earlier C. This shows itself in some compilers like clang. Cody Boone Ferguson looked at the source code of clang and reported that there is no way to override this requirement so these entries will fail to compile with clang. That's why he in some entries he fixed he did it by adding a function called pain(). :-)

NOTE for macOS users: please be aware that gcc under macOS is actually clang despite the fact it might appear to be gcc: no symlink and both gcc and clang exist but the gcc is clang which you'll see if you run gcc --version.

A tip and some fix methods from Cody: in the older days args to main() not given a type were implicit ints but when they're required to be char ** this can cause a problem. In some cases Cody was able to use a char * inside main() (see 1989/tromp/tromp.c and 1986/holloway/holloway.c for two examples though done slightly differently). In other cases he was able to dereference the pointers to be used like an int. He used other various techniques to get them to compile. In some cases this introduced a problem but typically if not always that problem exists with compilers that are less strict.

STATUS: compiled executable crashes - please help us fix

While such entries can compile, the resulting executable sometimes or always crashes.

NOTE: this does NOT apply to entries under the INABIAF status (though they're not mutually exclusive in some cases).

STATUS: uses gets() - change to fgets() if possible (in some cases getline() works)

Entries with this status use gets() which is unsafe because it has no limit on the length of the string. Cody Boone Ferguson has fixed several of these and he's working on others in between fixing other things. He provides some important notes:

First: in some cases changing the entry to use fgets() will break the entry and in some cases cause it to crash. Where this is known we will document it. Some of these Cody is also working on.

Second: you MUST check the output before and after to make sure that it remains the same. Sometimes the output might not be immediately obviously wrong but is. We will document known examples.

Third: gets() does NOT STORE the '\n' but fgets() DOES! This is one of the reasons some of the entries break when changed to fgets(). Cody has fixed some of these but there are others he hasn't had time to address and/or even discover yet.

Fourth: just because you don't see the string gets in the code does not mean it's not used. It is after all the Obfuscated C Code Contest! :-) Sometimes it will be in the Makefile and other times it will be obfuscated in other ways. Compilers and linkers tend to warn about its use and this is a good way to find entries that use it even if it's not visible in the code.

NOTE: this status is not necessarily mutually exclusive with the INABIAF (it's a bug not a feature) status. The reason for this is due to warnings during linking or runtime, sometimes causing confusing output.

STATUS: missing file(s) - please provide them

In these entries one file or multiple files are missing from the repo. In some cases these files can be found on the IOCCC website but in other cases they are entirely absent. In this case you'll probably have to contact the author (unless you are the author! :-) ).

STATUS: missing make rules - please provide them

In these entries one or more make rules noted by the author and/or judges is/are missing. You might consider looking at the archive as a good place to find them.

STATUS: INABIAF - please DO NOT fix

INABIAF: It's not a bug it's a feature :-)

Entries with this status should NOT be touched (unless they have another status that suggests that issue can be changed): they are system specific by design or are other things that are not actually bugs even if they appear to be. But are noteworthy nonetheless.

NOTE: the definition of this status changed over time. At one point it was when something was noted by the author, the judges, a consequence of earlier requirements for winning entries or the purpose was to do something that might appear to be buggy. An example of system specific entries:

1984/mullender (see below and the faq for a version that works in modern systems) is very system specific and was before system specific winning entries were discouraged. This is an all time personal favourite of Landon Curt Noll.

An example where a crash is not a bug: 2019/endoh is supposed to crash. There are others that are also supposed to crash or that are known to segfault but are considered features.

As of 10 April 2023 the definition changed for a second time (the first time was 07 April 2023). If something is noted by the author as a known bug or limitation it need not be fixed unless it impacts the usability of the program or removes instructional value. An example where a crash undocumented needn't be fixed is 1984/laman. On the other hand the fixes made by Cody Boone Ferguson in 1990/theorem were useful.

Nonetheless we challenge you to fix these entries for educational/instructional value and/or enjoyment but we kindly request that you DO NOT submit a pull request! If you can't figure it out you're invited to look at the git diffs, where there are some (some were fixed earlier on but rolled back due the fix feeling like tampering).

NOTE: in the case of gets() we've fixed some to avoid the warning of the compiler, linker or even during runtime, depending on the system. In one case the fix actually prevents confusing output (though that was not the only fix made).

Exception: your own entries

Of course if you're the author you're welcome to fix your own entry (or else suggest that they're fixed)!

STATUS: requires a compiler supporting -traditional-cpp - alternate code requested

NOTE: all of these appear to be fixed

Entries with this status need a compiler that support -traditional-cpp. gcc supports this but clang does not.

Please be advised that, as noted above, gcc under macOS is actually gcc even if it looks like it's gcc (the programs are the same, they're not symlinks but both are clang).

If you do wish to provide an alternate version of the program that does not need compiler supporting you are welcome to summit such code via a GitHub pull request and we will be happy to credit you in the entry's README.md file.

NOTE: as of commit fa8a9b8b28 we believe that all the entries with this problem have been fixed.

List of entries by year, sorted in alphabetical order

1984

1984/laman (README.md

STATUS: INABIAF - please DO NOT fix

This entry will very likely crash or do something else if you run it without an arg.

1985

1985/applin (README.md

STATUS: doesn't work with some platforms - please help us fix

Yusuke Endoh provided a fix for gcc but Cody Boone Ferguson observed that this does not work under macOS. It prints H???????? with additional ?s printed as it continues to run.

We have not had a chance to try and fix this yet but you're welcome to have a go at it.

1986

1986/august (README.md)

STATUS: INABIAF - please DO NOT fix

This entry is known to segfault after printing its output. It was documented by the judges and shouldn't be fixed.

1986/hague (README.md)

STATUS: uses gets() - change to fgets() if possible

This entry uses gets() which is unsafe. In particular the buffer size is a mere 81 and it does not read a single string at command invocation but instead until the program is terminated. This size can be increased to start out but it would be better if it used fgets(). This will be addressed in time but is noted here as a reminder.

The way this entry is formed has made it not as simple as some of the others that have been addressed.

1986/holloway (README.md)

STATUS: INABIAF - please DO NOT fix

Cody Boone Ferguson fixed this for modern systems but he points out a warning that should NOT be fixed; he experimented with trying to fix it but it did not work, either segfaulting or not displaying the correct output. Thus:

holloway.c:15:11: warning: incompatible pointer types initializing 'char *' with an expression of type 'char **'; dereference with * [-Wincompatible-pointer-types]
    char *t = s;
          ^   ~
              *

is NOT a problem and should NOT be changed. Neither are:

holloway.c:14:1: warning: return type defaults to 'int' [-Wreturn-type]
   14 | main(m1,s) char **s; {
      | ^~~~
holloway.c: In function 'main':
holloway.c:14:1: warning: type of 'm1' defaults to 'int' [-Wmissing-parameter-type]
holloway.c:15:15: warning: initialization of 'char *' from incompatible pointer type 'char **' [-Wincompatible-pointer-types]
   15 |     char *t = s;
      |               ^
holloway.c:23:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
   23 |             for(a=f;a<j;++a)if(tab1[a]&&!(tab1[a]%((long)l(n))))return(a);
      |                      ^
holloway.c:24:9: note: here
   24 |         case g:
      |         ^~~~
holloway.c:34:1: warning: control reaches end of non-void function [-Wreturn-type]
   34 | }
      | ^

or any others.

1987

1987/lievaart (README.md)

STATUS: possible bug (possibly depending on system) - please help test and if necessary fix

This might not work right. When Cody Boone Ferguson runs it he gets something like:

$ ./lievaart
Level:5
You:2
You:3
You:^C

However he also hasn't played Othello or if he has it was a very long time ago, so maybe he's doing something wrong.

1988

1989

1989/robison (README.md)

STATUS: INABIAF - please DO NOT fix

This program will crash with numbers with non-binary digits.

1989/westley (README.md)

STATUS: main() function args not allowed - please help us fix

Although Cody Boone Ferguson fixed this for some of the versions that are generated (see below tip) it will not work for all. He noted that trying to fix it in some cases causes a segfault and in other cases it fails to generate some of the files (others are okay) at all (empty files).

He gives these tips on the problem: main()'s second, third and fourth args are supposed to be a char **. This didn't use to be the case and some compilers like gcc don't complain. clang however does. Cody was able to get main() to be correct BUT a feature is that it uses ROT13 to decrypt the function znva to be main in generated files (see the README.md for details). Since that function does not have the correct types when converted to main() it fails to compile. But as he said changing the type causes either a segfault or files not generated at all. ver1, ver2 and ver3 are the problematic ones. The segfault happens when running the main program. Cody fixed that but as noted as for the generated files only ver0 will compile with clang.

1990

1990/jaw (README.md)

STATUS: INABIAF - please DO NOT fix

Cody Boone Ferguson fixed the scripts to work in modern systems. He notes however that the command in the try section, the one to test the official C entry, appears (the keyword!) to not work with macOS, giving:

$ echo "Quartz glyph jocks vend, fix, BMW." | compress | ./btoa | ./jaw
oops: Undefined error: 0
oops: Undefined error: 0

However this is because the entry uses perror() and it just so happens that the default errno of 0 gives that result. For instance if you run the following C program under macOS you will get undefined error but if you do it under linux you'll likely get success.

#include <stdio.h>
#include <errno.h>
#include <string.h>
int main()
{
    errno = 0;
    printf("%d, %s\n", errno, strerror(errno));
}

In fact the condition which is in the a() function on line 18 of the entry namely:

I k>16)

is true on both linux and macOS, with k being equal to 22!

Should the entry use perror()? Perhaps not but we're not sure of its purpose so it should stay with this note.

1990/theorem (README.md)

STATUS: known bug - please help us fix

Cody Boone Ferguson fixed many bugs that prevented this from working properly (including segfaults) but one bug known to exist remains: if theorem_bkp or fibonacci is passed two zeros the program will enter an infinite loop, printing 0 over and over again (another condition where this occurred was fixed).

Cody provides some hints here:

  1. The function in theorem.c that matters is w (see below for definition).
  2. However adding checks for the value being > 0 does not work due to the way the code is generated. See below.

w() looks like this:

w(g,R,u)float*g,u;char R;
/**/{int b,f;if(A>2){A=atoi(a[1]);b=atoi(a[2]);while((f=A+b)<15000){printf("%d\n",f);A=b;b=f;}}}

But as far as point 1 above changing it to be:

/**/{int b,f;if(A>2){A=atoi(a[1]);b=atoi(a[2]);while(f!=0&&(f=A+b)<15000){printf("%d\n",f);A=b;b=f;}}}

and similar (like checking >0, doing a do..while, doing an if before the while etc.) cause compilation errors.

Can you fix this? We welcome your help!

BTW: one of the important fixes for fibonacci to work is:

-/**/{int b,f;A=atoi(++a);b=atoi(++a);while((f=A+b)<15000){printf("%d\n",f);A=b;b=f;}}
+/**/{int b,f;if(A>2){A=atoi(a[1]);b=atoi(a[2]);while((f=A+b)<15000){printf("%d\n",f);A=b;b=f;}}}

Observe the check for the number of args and the calls to atoi() have been changed a bit too.

1990/westley (README.md)

STATUS: INABIAF - please DO NOT fix

This entry will crash without an arg. At this time this is not considered worth fixing so it should not be fixed.

STATUS: known bug - please help us fix

However any input not a number > 0 will make the program enter an infinite loop. This will be fixed in time but it's noted here for now.

1991

1991/dds ([README.md)(1991/dds/README.md))

1991/dds.alt ([README.md)(1991/dds/README.md))

STATUS: INABIAF - please DO NOT fix

If the BASIC file cannot be opened for reading or the output file cannot be opened for writing the program will crash. This is not a bug but a feature. Please do not fix this except for the challenge.

Please also note that for clang you have to use dds.alt not dds.c.

STATUS: uses gets() - change to fgets() if possible

That being said the compiled code uses gets() not fgets(). Can you fix this? You might find that the s array is relevant but if you do change it please make sure to test all functionality!

1991/westley (README.md)

STATUS: INABIAF - please DO NOT fix

There is a very simple way to always win. The program doesn't catch you and as someone called Cody's late grandmother said to him: 'it's not cheating unless you're caught'. :-)

Please don't try and fix it as it's not a bug and was actually documented as a possibility. Can you find out how?

1992

1992/buzzard.1 (README.md)

STATUS: INABIAF - please DO NOT fix

This entry will crash without enough args (2). At this time this is not considered a bug to fix so it should not be fixed.

1992/kivinen (README.md)

STATUS: known bug - please help us fix

When you start the program everything starts to move over to the right side and then ends. Yusuke Endoh pointed out that if you click the mouse it takes it back towards the centre but this should probably be fixed.

1992/lush (README.md)

STATUS: doesn't work with some compilers - please provide alternative code

We used a patch from Yusuke Endoh to get this to work but it only works with gcc. Unfortunately due to the way the entry works and the fact that other compilers like clang have different warnings and errors this simply does not work with them. Can you help us?

1993

1993/plummber (README.md)

STATUS: INABIAF - please DO NOT fix

If not enough args are specified this program will likely crash or do something else. This should NOT be fixed.

1994

1994/ldb (README.md)

STATUS: known bug - please help us fix

Cody Boone Ferguson fixed this to compile with modern systems (see the README.md file for what had to change) but the entry also used gets(). This could overflow long lines. Cody changed it to fgets() but this introduces another problem namely that newlines can be printed if the line length < 231.

This seems like a worthy compromise but it would be ideal for it to never print a newline unless that's the line itself (a blank line).

Cody will be looking at this later on.

1994/schnitzi ([README.md])(1994/schnitzi/README.md))

STATUS: uses gets() - change to fgets() if possible

The buffer size of this entry is 100 which is very easily overflowed with gets() which it uses. Changing it to use fgets() is difficult. Even changing the buffer size can cause compilation errors and even when that is fixed it will not translate to the generated file. The buffer size was changed but to make it the same functionality it was changed back.

Cody Boone Ferguson explains the magic of how this entry works which will be necessary if this entry is to be fixed, below.

The magic of 1994/schnitzi and how it flips text

The problem is getting the generated code to use fgets() (once it even compiles which is easy to do) and also have the updated buffer size be the same. The generated output, when changed to fgets() failed to compile. The buffer size, when using gets() is still the same.

The real problem is with formatting the code. Take a look at the interesting comment as well as the int r=0,x,y=0 at the top of the file. If you look at each column go down that column you can see how it spells out the code! For instance the first column looks like:

i
n
c
l
u
d
e
 
<
s
t
d
i
o
.
h
>

If you join the lines you end up with:

#include <stdio.h>

If you look at column 25 which is the end of the word 'mh111' and you go down to the next row you'll see a 0 and if you go one row down another 0. This is the buffer size, 100, for u! The column to the left is the same for the t variable.

Thus it seems that in order to get the generated output correct one needs to provide the correct input in comments or possibly by rearranging some of the code (this was actually required to make the generated code compile at all when changing the buffer size, see below).

Important points:

Getting this entry to use fgets() is easy but the problem is you're supposed to be able to feed the source to the program and the output of that will be compilable. It however will create compiler errors. So it's not just changing the code to get it to use fgets()! I (Cody) already did this before I noticed the other part which is why I rolled that part back. I did increase the buffer size but that only works on the original source.

To say just how sensitive this entry is: even a space, lack of space or a character, wrong character, lack of character or character in the wrong place can cause a compilation error! Make sure that the output of:

./schnitzi < schnitzi.c

can be compiled and the output of that new program when fed itself can also be compiled!

1994/shapiro (README.md)

STATUS: missing file - please provide it

Cody Boone Ferguson noted that the README.md file refers to an alternative version of the code that is not obfuscated but it is missing from the entry directory and the archive. Do you have this file?

We would be grateful if you could provide it to us. If you can provide this file you might consider removing this entry from this file as well but if not we'll take care of it.

Important reminder to fix the -1 value check for getc():

Cody wants to remind you that he fixed the code to not use -1 for the return value of getc(); this is important because EOF is NOT guaranteed to be -1 but rather any negative value. On systems where EOF != -1 the program would enter an infinite loop until the program crashed, by chance reads a -1 or was killed. See the README.md for more details. If you don't feel comfortable changing it to EOF Cody will happily do it for you but otherwise go right ahead. We'll credit you in the README.md file regardless.

1995

1995/cdua (README.md)

STATUS: known bug - please help us fix

This did not originally compile under macOS and after it did compile under macOS, it crashed. Cody Boone Ferguson fixed these problems.

However he observed that sometimes the program asks the user to hit return a second time to resume solving the maze. It does not always happen. It doesn't seem to be related to making it work under macOS as all that did was removing some invalid prototypes and use printf() instead of the invalid pointer to it (incompatible type). Besides that it happened under linux where there was no compilation error or crash.

1996

1997

There was no IOCCC in 1997.

1998

1998/schnitzi (README.md)

STATUS: INABIAF - please DO NOT fix

Cody Boone Ferguson fixed this to work for modern systems but he notes a couple compile warnings to ignore.

First if you get the warning:

warning: incompatible implicit declaration of built-in function 'printf' [-Wbuiltin-declaration-mismatch]
   11 | void  g(){ O=j; printf(_); }
      |                 ^~~~~~

please do NOT change it! Doing so will break the generated output.

Another warning that was introduced but should be ignored (it's required) is:

warning: assignment to 'char *' from incompatible pointer type 'char **' [-Wincompatible-pointer-types]
   55 | main(int v,char **c){ O=r_; _d=c;
      |                               ^

Please DO NOT change this either.

If there are any other warnings triggered by your compiler please DO NOT fix those either!

Another important note is that as the number passed into the program gets bigger the number of lines of output gets substantially larger. For instance:

$ ./schnitzi 9|wc -l
  771999

1999

There was no IOCCC in 1999.

2000

2000/primenum (README.md)

STATUS: INABIAF - please DO NOT fix

This program does not do what you might think it does! Running it like:

./primenum 13

will seemingly wait for input exactly because it is waiting for input. See the README.md file or look at the source.

It also has main() return void even though this is non-standard. Please do not fix this (in fact it was originally done but rolled back).

2001

2001/anonymous (README.md)

STATUS: known bug - please help us fix

This entry seems to no longer work and we would appreciate any help from anyone who can fix this. Cody Boone Ferguson has the following hints that might help but he has no system where he could test it. Yusuke Endoh wrote a little bit about it that might or might not help but he too could not get it to work.

Tips from Cody:

  • Try a beautifier on the original C code.
  • Use cpp to make the functions easier to parse. For instance if you're in the directory try cpp -E anonymous.cp > anonymous.cpp and look at that file to see the functions. It might or might not be helpful to use cpp on the beautified source.
  • After beautifying it try changing references of the macros (where not too complicated) to their definitions. For instance in vim you might do: :%s/\<l\>/int */g and then delete the line that was changed to #define int * int* (or else do a range substitute so it's not changed). You might not need this if you use the cpp. This might be useful anyway to more easily test things.
  • If your system has a setarch tool that might or might not be of help (I'm not too familiar with its internals).
  • The code appears to do everything from one call to exit(3) but it makes use of the ternary operator and possibly the comma operator.
  • Check the Makefile for the defines but also observe that those are in the source file. It appears that the entry might try compiling as well but that's from a quick glance.
  • The original main() started like: main (char *ck, char **k) but we made it compilable for clang by changing it to be: main (int cka, char **k) { char *ck = (char *)cka; which might or might not be good.
  • The author warns that only simple source (once compiled) would work so make use of the provided source file 2001/anonymous/anonymous.ten.c. To compile try make anonymous.ten from the entry directory which you can then run the entry on. Note that it needs to be compiled as a x86 program.
  • The program will to an extent destroy files it is used on. See the author's warning in their comments on that.

2001/bellard (README.md)

STATUS: possible bug (possibly depending on system) - please help test and if necessary fix

Cody Boone Ferguson fixed an initial segfault and he also fixed the supplementary program to test the entry on to not segfault and seemingly work but he has no 32-bit system to test any further fixes and we would greatly appreciate anyone's help! It appears that this entry will require major debugging and to make it work one might need to have a deep understanding of the ELF format.

2002

There was no IOCCC in 2002.

2003

There was no IOCCC in 2003.

2004

2004/burley (README.md)

STATUS: known bug - please help us fix

Cody Boone Ferguson fixed this to compile with clang. He notes however that both prior to the fix (with gcc) and after the fix (gcc, clang) it does not work: it allows input of the bet but after it prints the hand it does not do anything with your next move. Cody provided the following notes and tips (including possible reasons it doesn't work):

  1. Originally the jmp_buf was just an int p[4][1000].
  2. The setjmp.h header file was not included so the calls to longjmp() had not only the wrong number of arguments but also implicitly returned int when it actually returns void. This means that the comma operator had to be used to get the binary expressions to work. It might be this is part of the problem. It's possible that actually changing this introduced it to not work as some old entries actually use invalid prototypes and work but changing them to use the proper prototype breaks them.
  3. Another possible problem is the abuse of setjmp() and longjmp() which is known to be a problem, at least as he interprets it in his tired head (and less experience with longjmp). In particular:

The longjmp() routines may not be called after the routine which called the setjmp() routines returns. See also the NOTES section of the linux man pages for setjmp(3) and longjmp(3).

  1. The main() originally returned a call to main() which appeared to be an infinite recursion at least as it was; now it returns a call to poke() (since it's a poker game) which has the same number and type of args (1, char *) that main() originally had. This appears to not be an infinite recursion but I might be reading it wrong. Changing it to not return itself and the same problem occurs so perhaps this is not the problem. It's possible that the initial call to the poke() function is incorrect.
  2. It might be that the requirement of the comma operator in modern compilers is a problem. Perhaps some instances of ,1 should be ,0? That seems plausible as they are often used with the && operator.
  3. As well main() had only one arg, a char *, and there was a (seemingly) needless cast to char * from gets(). This cast remains in the code however.
  4. The code no longer uses gets() but fgets(); this is not the problem however.

2004/gavin (README.md)

STATUS: compiled executable crashes - please help us fix

STATUS: doesn't work with some platforms - please help us fix

Segmentation fault will occur in some systems. For instance on macOS with the arm64 chip:

./gavin > kernel

When trying to link gavin.o to produce sh, the linker generates:

Undefined symbols for architecture arm64:
  "start", referenced from:
     -u command line option
     (maybe you meant: __start)
ld: symbol(s) not found for architecture arm64

We believe that this simply won't work with non x86 specific systems but perhaps you have a fix? We welcome your help!

Recent 2004/gavin mods:

Although not related some recent changes were made to 2004/gavin to let it compile under clang. The following patch was applied:

diff --git a/2004/gavin/gavin.c b/2004/gavin/gavin.c
index c967b7e..2082b49 100644
--- a/2004/gavin/gavin.c
+++ b/2004/gavin/gavin.c
@@ -1,8 +1,9 @@
+int main(int t, char **q, char **d) { return cain(t, (int)q, (int)d); }
 #define G(n) int n(int t, int q, int d)
 #define X(p,t,s) (p>=t&&p<(t+s)&&(p-(t)&1023)<(s&1023))
 #define U(m) *((signed char *)(m))
 #define F if(!--q){
-#define I(s) (int)main-(int)s
+#define I(s) (int)cain-(int)s
 #define P(s,c,k) for(h=0; h>>14==0; h+=129)Y(16*c+h/1024+Y(V+36))&128>>(h&7)?U(s+(h&15367))=k:k

 G (B)
@@ -52,7 +53,7 @@ else

 G (_);
 G (o);
-G (main)
+G (cain)
 {
   Z, k = K;
   if (!t)

The original Makefile from 2004 had the following to say about this entry:

# Special flags for the gavin entry
#
# FYI: Older versions of GCC have a bug in -O2 optimization, hence -O1
#
GAVIN_OPT= -O1
GAVIN_FLAGS=\
        '-DY(m)=*((int*)(m))'\
        '-DE(f,a,b,c)=((G((*)))(f))(a,b,c)'\
        '-DM=for(D=0;D<786432;D++)'\
        '-DZ=int i=0,j=0,h,n,p=393728,s=26739,C,D'\
        '-DV=0x90200'\
        '-DK=0'\
        '-DR=while((C=E(V-8,100,0,0))&3&&(D=E(V-8,96,0,0))|3){'\
        '-DL(c,d)=E(V+8,100,c,0);R}E(V+8,96,d,0);R}'

# ...

# Best of Show
#
gavin: gavin.c
        ${CC} ${GAVIN_OPT} -o gavin ${GAVIN_FLAGS} gavin.c
        ${RM} -f kernel
        ./gavin > kernel
        ${CC} ${GAVIN_OPT} -c ${GAVIN_FLAGS} -DB=_start '-Dputchar(a)=' gavin.c
        ${RM} -f sh
        ${LD} -s -o sh gavin.o
        ${RM} -f vi
        ${CP} sh vi
        ${RM} -f fs.tar
        ${TAR} -cvf fs.tar sh vi gavin.c gavin.hint prim

gavin_clean:
        ${RM} -f sh vi kernel gavin.o

gavin_clobber: gavin_clean
        ${RM} -f gavin fs.tar

gavin_files: boot.b lilo.conf prim gavin_install.txt

The current (Makefile was modified to try and fit into the current IOCCC build environment.

2005

2005/giljade (README.md)

STATUS: doesn't work with some platforms - please help us fix

Cody Boone Ferguson noted that this requires both 32-bit CPUs (data size?) and also cannot have the optimiser enabled. It might be that it can be fixed, perhaps by changing the int sizes and bitwise operations, but if not this will not work with some systems like modern Macs as Apple has made it quite difficult to compile 32-bit applications (thanks a lot Apple for ruining some IOCCC entries! :-) ).

It's quite probable that non x86 related CPUs will also not work: it's hard to know because Cody's only non-x86 (x86_64 in particular) system is the MacBook Pro Max with the M1 chip which is arm64 and unfortunately specifying -m32 is invalid on that system (might be on Intel 64-bit Macs as well but he hasn't had one since before November 2022).

2005/mynx (README.md)

STATUS: INABIAF - please DO NOT fix

Cody Boone Ferguson notes that, though probably obvious, this entry will not work with https. He changed the code to scan for https too (it exited before) in case someone comes up with a clever command line to make it work but the problem is a secure connection has to first be set up in order to give http commands. This is not a bug but it's worth pointing out as it won't work on as many websites as it used to including the IOCCC website itself.

2006

2007

2008

2009

2010

These years did not have an IOCCC.

2011

2012

2013

2014

2014/vik (README.md)

STATUS: known bug - please help us fix

Cody Boone Ferguson discovered a bug that shows itself in some cases (it works in others) when working on his winning 2020 Enigma machine ('Most enigmatic) entry. See his README.md for details (search for vik in the file).

He provides a tip in testing the problem: it might help to use his Enigma machine to find problems as it will allow you to verify what is correct and what is not. Again see his README.md for details!

2015

2015/endoh3 (README.md)

STATUS: missing files - please provide them

With Yusuke's analysis of his entry which can be found here he shows a tarball with source files that work with his entry, a mock emulator for 1984/mullender. Unfortunately he does not have the tarball available for download and only showed a few (which Cody Boone Ferguson added to the repo).

Cody has his email and WILL be contacting him in time but we note it here anyway for now.

2018

2018/algmyr ([README.md)(2018/algmyr/README.md]))

STATUS: INABIAF - please DO NOT fix

This entry is known to crash if a file cannot be opened. This is noted by the author and is easy enough to fix but need not be.

2018/hou (README.md)

STATUS: INABIAF - please DO NOT fix

When you run it you will see something like:

$ ./prog < ioccc.json > ioccc.html
Assertion failed: (rulez), function C, file prog.c, line 124.
Abort trap: 6

but this is expected and the file ioccc.html will be generated properly.

2019

2019/ciura (README.md)

STATUS: known bug - please help us fix

Cody Boone Ferguson fixed the scripts so that the locale is correct (or at least correct for the commands to be run without error, notwithstanding English which isn't a problem) but he notes that under both macOS and fedora linux the alternative language scripts don't report anything. This happened before and after the fix to the scripts.

Maybe it's the locale or maybe it's the dictionary files but it appears that they did work for some. If you can identify the problem we would appreciate the help!

2019/endoh (README.md)

STATUS: INABIAF - please DO NOT fix

As a backtrace quine this entry is SUPPOSED to segfault so this should not be touched either.

2020

2020/burton (README.md)

STATUS: INABIAF - please DO NOT fix

This entry is known to crash if no arg is specified. Although easy to fix it is documented and should not be fixed (of course you may fix it to see if you can but it shouldn't be made into a pull request).

It will also show funny output with more than one arg. This should not be fixed either. But can you figure out why this happens?

2020/ferguson1 (README.md)

STATUS: INABIAF - please DO NOT fix

There are some things that might appear to be bugs but are actually features or things that are misinterpreted as bugs. See his bugs.md and troubleshooting.md files for details.

2021

2022

These years did not have an IOCCC entry.

Final words

We hope this document was of use to you in determining which entries are known to have a problem, what entries are known to have features that are not bugs and so on. We also thank you for going through this document and, if you propose any fixes via a pull request or otherwise, we thank you as well for the help!