Reasons for Rubyists to Learn C

By Najaf Ali

Why Bother?

Liberation From Stupidity

The C programming language's only failing is giving you access to what is really there, and telling you the cold hard raw truth. C gives you the red pill. C pulls the curtain back to show you the wizard. C is truth.

Why use C then if it's so dangerous? Because C gives you power over the false reality of abstraction and liberates you from stupidity. Zed Shaw, Intro to Learn C The Hard Way

That nagging feeling of not really knowing how your computer works? Yep, learning C fills in a lot of the details, fast.

Yes, developer time is more expensive than CPU time. That doesn't stop you from being a better developer by understanding how your computer works.

As rubyists, a lot of us come from PHP backgrounds and haven't ever had to work with computers at a systems level. Learning just a little C teaches you how your OS allocates memory, how processes work at a fine-grained level and of course, how to write programs that run ridiculously fast.

Use only the memory that you need

Hello world in ruby:

puts 'Hello, world!'

the equivalent C:

#include <stdio.h>

int main() {
  printf("Hello, world!\n");
  return 0; //thanks @threedaymonk
}

Using memory usage analysis tools like valgrind show that running the ruby version allocates in the region of 3MB of memory, while the compiled C version uses only a few kilobytes.

C is compiled, ruby is interpreted. This is a trite example, and all the tasty abstractions and conveniences that ruby give you make you beyond powerful as a programmer.

This is just a gentle reminder that all that creamy goodness has a price, and you don't have to pay it if you don't need to. Learning C gives you the power to manipulate the computer in an incredibly precise way should you choose to do so.

Blazingly Fast Software

There's a reason other languages aspire to 'c-like performance'.

Much of your favourite software is written in C

Wouldn't it be nice to be able to read the code and even contribute?

Stuff You Should Be Aware Of

  • Pointers. They point to things in memory. Not as hard as people make them out to be, and you must use them in C for any sort of abstraction. Related and equally important is the concept of function pointers, which give you the means to do all the dynamic method lookups you like so much...
  • You can have your polymorphism if you want it. If you actually know what polymorphism is you can have it in C. Just don't expect it to be packaged up in a neat little inheritance system that you might find in Ruby.
  • Type declarations will give you the biggest ROI starting out. Being able to figure out how to read the syntax for and declare a pointer to a function that returns a pointer to a struct for example needs to be understood intuitively.
  • Memory allocation, the stack and the heap. The stack is where your function contexts are pushed onto and popped off. The heap is the pool of memory that you can allocate for usage in your program (which incidentally, is not actually a heap anymore).

    If you don't de-allocate any memory that you use from the heap, you get memory leaks. They're bad, so use memory usage profiling tools like valgrind to weed out and fix them.

  • Linking Libraries. If you want to build anything larger than what you would fit in a single file, you'll need to figure out how to tell your compiler to link libraries and where to find them.

Caveat: You Probably Shouldn't Write Production Software with 'just a little' C

Writing C without a good understanding of how memory is accessed by your code can leave you open to some rather spectacular security holes.

Shellcoding is the practice of injecting machine code into your software via user input with the intent of tricking it into running the malicious code.

Sounds hard or impossible? If you're not suitably paranoid about this, I recommend you peruse the free sample of The Shellcoders Handbook and see if it doesn't change your mind.

Side Notes Go is looking really nice these days

For actually writing software, Go is turning out to be a performant alternative that is quite comfortable to program in. It also insulates you from the shellcoding attack vector by handling memory management for you, though that has it's own sets of pros and cons (hello garbage collection!)

Resources for learning C

  • Learn C The Hard Way - Zed Shaws guide to learning C. Just about the best guide I've seen to picking up C. Includes a lot of the icky parts like linking libraries and creating to Makefiles. Immensely useful.
  • Mastering Algorithms With C - While it sounds like it might be quite abstract, this book dives into low-level implementation details, including topics like the stack frame and tail-call optimization.
  • K & R C - AKA "The White Bible". A bit dated but good for historical value and a thorough reference.