Version 0.3.
Copyright 2008–2011 Peter Hosey.
This work is licensed under a Creative Commons Attribution 2.5 License.
A recurring theme in many corporate-programming horror stories is the myth that the more lines of code that you write, the more productive you are. This article aims to debunk this myth once and for all, and also attack bad code in general.
All of the code on this page is in C, and with the exception of the Shortest Possible Hello World, all of it is compliant with the ISO 9899:1999 (aka C99) standard.
If you want to build and run the Best and/or Worst examples yourself, I recommend downloading the zip archive (each one is linked below) and using the included Makefile. The command to build the sample program, regardless of which one it is, is make helloworld, and the resulting program executable is named helloworld.
If you're not a coder, here are some things you should know beforehand:
!0
is 1. !anything else
is 0.42 == 42
, whereas 43 != 42
.Like any Hello World, all this does is print (that is, display) “Hello World!”. But it does so in the most convoluted way I can imagine. If you're interested in compiling and running the program yourself, here's a zip archive.
#include <sys/types.h> #include <stdlib.h> #include <stddef.h> #include <stdio.h> #include <string.h> #include <math.h> int main(void) { FILE *file = fopen("helloworld.c", "rb"); fseeko(file, 0, SEEK_END); off_t len = ftello(file); size_t buflen = len / 0x4e; char *buf = malloc(buflen); fread(&buf[buflen - 1U], 1U, 1U, file); fseeko(file, 139, SEEK_SET); char buf2[16]; fread(buf2, 1U, 4U, file); char translation[] = { 2, 28, 32, 39 }; for(ptrdiff_t i = 0.0; i < 1; ++i) { buf2[0] += translation[0]; buf2[1] += translation[1]; buf2[2] += translation[2]; buf2[3] += translation[3]; } memcpy(buf, buf2, 4U); fseeko(file, 512.0, SEEK_SET); fread(&buf[4], 1U, 2U, file); off_t delta = 66; buf[5] -= delta; buf[5] = floor(M_PI * 10.18591635788130148921); buf[6] = buf[5] + (delta - (delta / 6.0)); fseek(file, 454L, SEEK_SET); fread(buf + 7, 1U, 2U, file); fseek(file, -421, SEEK_CUR); fread(&buf[9], 1U, 2U, file); long long magnitute = buf[10]; buf[10] = buf[011]; buf[011] = magnitute; fseek(file, -24, SEEK_END); fread(&buf[11], 1U, 1U, file); return !printf("%s\n", buf); }
This code is 50 lines long. By the standard that more lines of code == more productive coding, this represents a highly productive session.
If you have no coding skills at all, you probably don't recognize how bad this code is. No offense, but it's all magic to you. I intend to show you the alternatives.
This is the Hello World you typically see in programming books.
#include <stdio.h> int main() { printf("Hello World!\n"); }
Much shorter, isn't it? Clearly less productive. But there are other things wrong with it.
return 0;
for you, but you shouldn't rely on this. Again, be thorough. Return zero yourself.So the Canonical Hello World is clearly sub-optimal, though not nearly as bad as the Worst Possible Hello World. So what can we do to it?
This is the opposite extreme from the Worst Possible Hello World: that one was written to be as long as possible (or as long as I could think of, anyway), whereas this one is written to be as short as possible. It's a one-liner, not counting the #include
, and it is just 59 bytes long.
#include <stdio.h> main(){printf("Hello world!\n");}
This has its own set of problems.
There are exactly two spaces in this program. This is far too few. More whitespace is almost always better.
This code follows the “implicit int” rule of K&R (read: old) C: if you leave out the return type, the compiler assumes you mean to return int. This rule was deprecated in ANSI C, and since C99, it is completely illegal. You cannot use this in code that you want to conform to the ISO C standard.
A bigger problem (i.e. not a style issue) is the use of printf. This function is used for inserting values into a format string (f for formatted):
printf("The Answer to the Ultimate Question of Life, the Universe, and Everything is: %d\n", 42);
Whenever you use printf, printf has to go over that format string looking for format specifiers (like %d
) and interpolate the values into them — in this case, replacing %d
with 42.
But Hello World does not use this feature. It simply prints a static string. So we should use a function that doesn't waste time looking for places to insert values that weren't passed to it anyway. (For highly technical reasons, it is not possible for printf to avoid scanning the format string, even if no values were passed. Trust me.)
Finally, this code makes poor use of printf's return value. printf returns the number of bytes written. If this is fewer than the length of the number of bytes we should have printed, something bad happened, and we should report this fact to the user. This is called “error-handling” or “error-reporting”, and neither the Shortest Possible Hello World nor the Canonical Hello World do it. Instead, the Shortest Possible Hello World simply negates it: if printf wrote anything — even just one character (clearly a failure) — it returns 0, and if it wrote nothing (0 bytes), it returns 1.
(IMHO.) Also available as a zip archive.
#include <stdlib.h> #include <stdio.h> #include <sys/errno.h> #include <string.h> int main(void) { int success = fputs("Hello World!\n", stdout); if(success != EOF) { success = fflush(stdout); if(success != EOF) return EXIT_SUCCESS; } fprintf(stderr, "ERROR: fputs did not succeed in writing our message string (error returned: %s)!\n", strerror(errno)); return EXIT_FAILURE; }
The changes from the Worst, Shortest, and Canonical Hello Worlds:
!printf(…)
”?Note: These versions are not the shortest. And they do not have the most lines. But they are the best.
Good code (== productivity) is measured by readability, performance, and robustness, not by obvious-but-wrong measures like lines of code. If you really need to measure how productive your programmers are, learn whatever language they're using, at least enough to be able to read their code. If you still can't read their code after you know the language, something is probably wrong. But if some code isn't obvious, don't be afraid to ask them, just in case they thought of a clever solution to a difficult problem or performance issue.