Real Pirates Seek the C!

The Case for C as a Modern Development Language

Created by Clay Dowling

I Want Software Development To Be Fun

Why C?

The language is older than you.

50 years of language developments

It's Dead Sexy

No Seriously, Why?

Small and easy to understand

Rich ecosystem

50 years of language evolution

Real development with minimal tools

Modern Features

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

The Real Reason

A small language means fewer options

Fewer options ⇒ Focus on getting stuff done

Getting Stuff Done ⇒ Happy Developers

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))
.PHONY: all

$(PROGNAME):
	$(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})
					

Auto-Tools


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

F*ck Ups Happen

I am a mere mortal, and that's okay.

An Example


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
				

A Test Run


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

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

Run Tests With a 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 To The Rescue

Many common problems, with 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?

Challenges?

Further reading at ClayDowling.com

Thank You

ClayDowling.com