blogstrapping

Reminding Myself How To Write Simple C

I have written a little bit of C in the past, including a couple of actually useful programs. Mostly, however, I have used higher level languages -- especially Perl, PHP, and Ruby. I have decided to refamiliarize myself with basic C development, though, then learn more about writing good code in C than I ever learned before. I have half a dozen C books (give or take) lurking about my bookshelves waiting to be read.

The Syllabus (Or: What I Have Lying Around)

The list currently looks something like this:

  1. Practical C Programming by Steve Oualline

    This is not anywhere near the best written beginner level book for a programming language that I have ever seen, but it does present basic concepts of the language in a fairly clear, beginner oriented manner, so it will at least provide a gentle re-introduction to C, even if not a brilliant re-introduction. It is painfully slow, too, but I will surely manage to slog through it nonetheless.

  2. The C Programming Language by Kernighan and Ritchie

    'Nuff said.

  3. The Unix Programming Environment by Kernighan and Pike

    This book is basically the Unix companion to The C Programming Language. It seems likely to be the ideal follow-up to K&R for a Unix-phile like me.

  4. Mastering Algorithms with C by Kyle Loudon

    An algorithms book focused on C seems like a pretty good choice for continuing self-education in the language.

  5. Test-Driven Development for Embedded C by James W. Grenning

    My experiences with test-driven development just keep getting more rewarding. I want to carry the benefits of TDD with me from Ruby to C. I am also thinking about tackling some simple embedded development with Arduino projects as a way to sharpen my skills and have fun hacking at something new to me, though as the book's author points out embedded development is not a requirement for making effective use of TDD for Embedded C.

  6. Designing BSD Rootkits by Joseph Kong

    Along with The Unix Programming Environment, this points me squarely in the direction of a big part of the reason I chose now to start working on C familiarity: development for FreeBSD. Of course, the book contains some assembly language too, which is something I intend to learn (unlike C, it is not a language I have ever really touched before), but I may need some other resources to help sort out the assembly language bits. I suppose I will see when the time comes.

This is far from a rigid didactic plan; it is subject to change at any time. I guess I will take something of an "agile" approach to the learning path. I will use short, goal-oriented task iterations, reassess the plans for the next step as each iteration draws to a close, and so on -- though not in nearly so formal a manner as this description might make it sound, of course.

FizzBuzz (Or: Hello World For Internet Denizens)

In the meantime, I have managed to remind myself about enough C to write a fizzbuzz implementation in about five minutes without having to use any references in the middle of it:

#include <stdio.h>

int count = 1;

int main() {
  while (count <= 100) {
    if (count % 3 == 0) printf("Fizz");
    if (count % 5 == 0) printf("Buzz");

    if ((count % 3 != 0) && (count % 5 != 0)) printf("%d", count);

    printf("\n");

    ++count;
  }

  return (0);
}

Simple enough.

Compiler Choice (Or: Crummy Platforms Are Limiting Factors)

I decided to use LLVM/Clang as my compiler of choice for these investigations into C refamiliarization.

I have been using Debian GNU/Linux for much of this year due to some hardware requirements with my new laptop that are not yet properly supported in FreeBSD. The frustrations of dealing with a Linux-based system are much magnified since I used Linux-based systems much more regularly half a dozen years ago. Things have gone downhill in the interim, to put it gently. I will not go into detail here, though. I could fill a book with the shortcomings and annoyances of dicking around with what has started to feel like a rinky-dink excuse for a Unix-like OS.

I have an older laptop that was just lying around unused for a while. An acquaintance has been convincing me to let him mentor me into becoming a FreeBSD port maintainer. As part of preparing for that, I decided to install the preview release of FreeBSD 9.0 on that older laptop. Guess what comes next.

I installed Clang on the ThinkPad T510 running Debian, then I started trying to use it. No dice; something is broken. I started trying to find some guidance on where to look for a fix by plugging error messages into Google. This is an example:

$ clang fizzbuzz.c
In file included from fizzbuzz.c:1:
In file included from /usr/include/stdio.h:28:
/usr/include/features.h:323:10: fatal error: 'bits/predefs.h' file not found
#include <bits/predefs.h>
         ^
1 diagnostic generated.

I did not get very far, because it occurred to me I would probably get more done if I installed Clang on FreeBSD and discovered a complete lack of problems. On FreeBSD, I got this result instead:

> clang fizzbuzz.c

No command output -- just a useful little a.out file. It works like a charm. I get to add yet one more ridiculous, petty failure to the "no" column when tallying up reasons for whether I should use Debian instead of FreeBSD.

Clang itself, by the way, is working great so far.