My Favorite Takeaways from 21st Century C

Look- I’m a big fan of programming books. My most recent foray was into Ben Klemens’s 21st Century C. I’m already proficient with C in general, so why read yet another book on it? Well, my learning style is primarily iterative–which I suspect is true for many of us. A little review never hurt anybody. I’m often pleasantly surprised at some of the neat things that I didn’t internalize the first time around.

This blog post is not a review of 21st Century C. It’s just a brief tour of some of my favorite things that I learned while reading this book. A particularly keen reader might think “well these topics are already covered in x, y, z!” — you’re right! They are. By coincidence, I just happened to finally digest them in 21st Century C.

Array Decay

This is one of those connections that is made up of a couple of tiny little bread crumbs, but you can get on with your life and do everything you need to do with just one of those bread crumbs.

If you’re not new to pointers then you might know that a pointer can point to one item or the first of many. You might also know that an array is one or more items (though the latter is arguably more useful in most cases).

If you’re feeling particularly detail-oriented you might find that an array is just a memory address to the first element of the array. What values do pointers hold? Addresses.

Indeed, if you look under the hood of accessing an element of an array, you’ll just find pointer arithmetic staring back at you.

int nums[] = { 1, 2, 3 };
int a = nums[1];
int b = *(nums + 1);
assert(a == b);

Coincidence? Well, no. Even before reading 21st Century C this isn’t really new information to me. However, this looks like a duck, quacks like a duck, and walks like a duck.

So it’s a duck. Er, pointer.

Honestly what brings us together today is mawwiage. An array is just a pointer that is married to a block of stack-allocated memory. Nothing more, nothing less. This marriage is enforced by the compiler. Ever tried to reassign one array to another? Now that’s marriage til’ death do us part.

And that is how arrays “decay” into pointers.

Compound Literals

If you’re ever at a party, this one will make you really popular. You can use them to avoid “throw-away” variables for function calls like so:

int sum(int nums[], int len);

int main(void)
{
	int total = sum((int[]) { 1, 2, 3 }, 3);
	return 0;
}

Though, I have to admit, I find it less interesting what with all the hard-coded lengths there. Maybe you have a function you call with some vestigial parameter that never changes and you don’t feel like making a constant for a one-time deal:

void do_something(int *value);

int main(void)
{
        do_something(&(int){1});
}

Most of my usage of compound literals comes from combining them with…

drum roll

Designated Initializers

struct hash_table *table = malloc(sizeof(*table));
*table = (struct hash_table) {
	.hash = hash,
	.key_size = key_size,
	.equals = equals,
	.free_key = free_key,
	.free_value = free_value,
	.max_capacity = HASH_TABLE_INIT_SIZE,
	.entries = entries
};

Is way better than:

struct hash_table *table = malloc(sizeof(*table));
table->hash = hash;
table->key_size = key_size;
table->equals = equals;
table->free_key = free_key;
table->free_value = free_value;
table->max_capacity = HASH_TABLE_INIT_SIZE;
table->entries = entries;

Don’t you agree? Also, the second one is buggy because some of the fields that you don’t see aren’t zero-initialized. Speaking of zero-initialization, another cool thing about designated initializers is that any fields that aren’t named in the initialization are set to their zero equivalents.

Indeed, we can zero out a structure by simply not naming any of the elements:

struct game *g = malloc(sizeof(*g));
*g = (struct game) {};

Although, if you listen to the compiler warnings, ISO C doesn’t support empty initializer braces, so we can zero-initialize in a way where everyone is happy by slapping a 0 in there:

*g = (struct game) {0};

Er, I’m at the end of this post and I’ve only just realized how short the list is. That’s not to say these are the only takeaways from 21st Century C, but they are my favorites.

What are some of your favorite C-isms?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s