Real Pirates Seek the C!

Clay Dowling

Twitter @ClayDowling

http://claydowling.com/realpirates

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.

Make

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

$(PROGNAME): $(OBJS)
    $(CC) -o $@ $^

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

CMake

cmake_minimum_required(VERSION 2.8)

file(GLOB program_SRC
    "*.c"
)

add_executable(myprogram ${program_SRC})

Autotools

// 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

Prefer

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

Over

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

Trust Nothing

Write automated tests for all of your code

Use valgrind on your tests

Do not ignore valgrind errors

Test First

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));
    
    skill_destroy(a);
    skill_destroy(b);
}
END_TEST

Test Run

./test-genesyssheet
Unity test run 1 of 1
.....

-----------------------
5 Tests 0 Failures 0 Ignored
OK

Make Tests Part of Your Build

all: test product

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

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

Ecosystem

Many common problems.

Many common solutions.

XML

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

Json

  • cJSON - github.com/DaveGamble/cJSON - Light, fast, easy.
  • jansson - github.com/akheron/jansson - Full featured, good examples.

Network/REST Client

libcurl

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

Easy to mock/test code using libcurl.

REST Server

libulfius

Easy to test without mocking.

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

Database

Native, fast clients available for:

  • PostgreSQL
  • MySQL
  • SQLite
  • Redis
  • etc…

Questions?

Thank You

Twitter @ClayDowling

Slides at http://claydowling.com/realpirates