

An Interview with Brian Kernighan on C and The C Programming Language - AndreyKarpov
http://www.informit.com/articles/article.aspx?p=1960359

======
graeme
I started learning programming with K & R in January. Working through the
exercises was an amazing foundation in the thought processes programming
requires.

The language is simple enough that you're left with nothing to get in the way
of the problem in front of you, and you're forced to think of what is
happening on a very low level.

That low level understanding helped when I tried languages with more
abstractions.

------
telemachos
Over and above the interview, I'm very happy to see that K&R's _C Programming
Language_ will soon be released in ebook formats.

~~~
pjmlp
Sadly it won't get updated to new ways of doing C coding.

~~~
loungin
I've seen this mentioned several times. Is there a resource you recommend on
the 'new ways'? Asking out of curiosity, about to start a side project with C,
and I do have the text mentioned.

~~~
kragen
Hmm, here are some things that I do routinely that don't really show up:

ꙮ I always use enum instead of #define for numeric constants.

ꙮ I nearly always use inline instead of #define for small functions whose
efficiency worries me.

ꙮ As a result of those two things, I don't use #define much.

ꙮ Everything global is static unless it's in the public API provided by the
file.

ꙮ I use dynamic allocation a lot more than the C in the K&R book.

ꙮ I avoid integer function arguments and return values as much as possible,
because they're basically untyped, and I benefit from the limited static type
checking done by C compilers. I still use them for cases where I'm actually
counting or measuring something, and unfortunately for bitfields. When I'm
counting bytes, the correct type is usually size_t or ptrdiff_t, which
benefits humans and LP64 platforms, but doesn't get you much static type
checking benefit.

ꙮ As a result of those two things, I use arrays relatively sparingly.

ꙮ I basically never use function-static variables because they make thread-
safety very difficult if not impossible.

ꙮ Use const wherever applicable. It catches some errors, and it's not nearly
as draconian as in C++, so it doesn't cause as many problems.

ꙮ After some experience with C++, I usually "typedef struct foo foo", since it
costs me two words in the declaration and saves me the "struct" every time I
use "foo" later.

I don't know if these are the kinds of things people mean when they talk about
new ways of coding in C, or where to find them documented.

~~~
frou_dh
I like that idea of using a (presumably unnamed) _enum_ as a bag of constants
that aren't necessarily related. From the small amount of Go I tried, its
syntax for constants seemed a more evolved version of that.

What do you think is the minimum realistic preprocessor usage that can be got
away with? _#include_ \+ _#pragma once_?

~~~
gosu
I'd say that it's bad to put #pragma once in your minimal set, since it's
nonstandard. Why not use plain old include guards?

For me, container_of() is also indispensable. Although maybe it's on the level
of 'errno' as being "not really a dirty macro".

~~~
frou_dh
I know - I was just spitballing the minimum number, since guards require
conditionals too. Though, portability aside, you have to agree that it's
simply nicer, since it plainly states the intent without requiring a little
dance each time.

