Real Pirates Seek the C!   @ClayDowling

Why C?

Dead Sexy

  • It’s Dead Sexy
  • Born in 1972
  • It’s Older Than Most of Your Team

No, Seriously, Why?

  • Small and easy to understand
  • Rich ecosystem
  • 50 years of language evolution
  • Real development with minimal tools

Technical Reasons

  • Functional - Functions are first class objects
  • Object Oriented - Data and logic separated by default
  • Test Driven Development - Built in test features and robust libraries
  • Web Native - Libraries for easy self hosted web apps
  • Distributed - Libraries for remote interaction

Business Reasons

  • A small language ⇒ fewer options
  • Fewer options ⇒ Focus on getting stuff done
  • Getting Stuff Done ⇒ Happy Developers

Build Systems

Building Large Projects is Hard

Different build tools exist to make the job easier.

Build tools are their own programming language.


OBJS=$(patsubst %.c, %.o, $(wildcard *.c))

    $(CC) -o $@ $^

    rm -f $(PROGNAME)
    rm -f *.o


cmake_minimum_required(VERSION 2.8)

file(GLOB program_SRC

add_executable(myprogram ${program_SRC})


// Sorry, it's a beautiful
// mystery to me as well.

Pointers are Scary

Programming is like playing with a loaded gun. C cocks the hammer for you.

—Anonymous IBM Employee

Avoid Allocating Memory


struct stat sb;
if (stat("file.txt", &sb))


struct stat *sb = calloc(1, sizeof(struct stat));
if (stat("file.txt", sb))

Symmetry Is Your Friend

If You Write… Also Write…
malloc/calloc free
myobject_create myobject_destroy

Test First

Trust Nothing

Write automated tests for all of your code

Use valgrind on your tests

Do not ignore valgrind errors

You Will F*** Stuff Up

“I am a mere mortal, and that’s okay.”

Ferry aground

Sample Test

START_TEST(skillcmp_givenAandB_returnsNegativeOne) {
    skill_t *a = skill_create("A", 0, S_CATEGORY, S_ATTRIBUTE);
    skill_t *b = skill_create("B", 0, S_CATEGORY, S_ATTRIBUTE);

    ck_assert_int_eq(-1, skill_cmp(a, b));


Test Run

Unity test run 1 of 1

5 Tests 0 Failures 0 Ignored

Make Tests Part of Your Build

all: test product

product: $(OBJECTS) main.o
    $(CC) -o $@ $^

test: test-product
    valgrind test-product

test-product: $(TEST_OBJECTS) $(OBJECTS)
    $(CC) -o $@ $^ $(TEST_LIBS)


Many common problems.

Many common solutions.


  • libxml2 - Fast parser using document or sax style.
  • xpat - Light weight sax parser.
  • Apache Xerces - Do Not Use
  • Microsoft XML - Do Not Use


  • cJSON - - Light, fast, easy.
  • jansson - - Full featured, good examples.

Network/REST Client


If it’s a network protocol, libcurl speaks it.

Easy to mock/test code using libcurl.

REST Server


Easy to test without mocking.

Can have a server doing useful work in under an hour.


Native, fast clients available for:

  • PostgreSQL
  • MySQL
  • SQLite
  • Redis
  • etc…

Game Programming

  • An infinite array of tools
  • SDL is simple and well supported

Write Your Own Language

  • lex/flex to tokenize your input.
  • bison/lemon to parse your language grammar.
  • an old, well-solved problem.


Thank You   @ClayDowling