Hacker News Comments on
C Interfaces and Implementations: Techniques for Creating Reusable Software
Hacker News Stories and CommentsAll the comments and stories posted to Hacker News that reference this book.
Please check "The C Interfaces and Implementations" book by David Hanson . Someone has implemented the concept using his library that you can check and use .
Another excellent reference is the "The Linux Programming Interface" book by Michael Kerrisk that documents most of the API available under Linux .
Hanson's C Interfaces and Implementations  is one of the best books on the subject.
Strongly complemented by Sedgewick's Algorithms in C.
⬐ zengidI added both to my wish-list; Thanks!
This book (C Interfaces and Implementations: Techniques for Creating Reusable Software) has a whole section on it:
I'd recommend Ben Klemens' excellent book "21st Century C - Tips from the New School" . This book teaches you modern C techniques and, most importantly, the tooling that modern C programmers use (git, autotools, valgrind, etc.) It also covers commonly used libraries to help you from reinventing the wheel (GLib, POSIX standard, SQLite, libxml, & cURL.)
As mentioned in another post, David Hanson's "C Interfaces and Implementations - Techniques for Creating Reusable Software"  is a great book, stressing the design of good APIs. This book in particular might help you in your goal to become a better engineer.
On the free side, there's an excellent PDF by Jens Gustedt, "Modern C" . I've not read the whole thing but it seems like an in-depth look at C11.
John Regehr's blog "Embedded in Academia"  is a good resource for C programming. You'll learn a lot about weird edge cases and undefined behavior. He also has a recent post about teaching C, with suggestions for resources .
Much of the code in the fantastic C Interfaces and Implementations  is inspired by Modula-3. It's a fantastic book to work through after finishing K&R for anyone wanting to learn how to write safe and reusable C code.
(Regular HN readers will recognize the author of the top review on Amazon.)
⬐ nickpsecurityWow. Interesting to see the two converge that way. That's the glowing review I've seen of a book in a while. Guess I'm going to have to get it just in case. :)
I suggest C Interfaces and Implementations: Techniques for Creating Reusable Software by David Hanson. It focuses on helpful engineering practices for reliably and efficiently implementing algorithms in C.
I also second the recommendation for Peter van der Linden's Expert C Programming for its masterful treatment of how C really functions, including the surprisingly frequent areas in which real-world constructs produce "undefined behavior" from the perspective of the C standard.
"With OOP it's all about classes, abstractions, interfaces etc. and design patterns."
The ability to create abstractions is pretty much a part of any programming language, including assembler. They're a property of the structure of the code, not of specific language features. For example, in the Linux kernel, which is written in C, there's an abstraction called a file descriptor that represents a stream of bytes that your program can read/write, whether it comes from a file on a disk, a serial port, a pipe, etc.
Interfaces also exist in all languages: they're just a well-defined set of calls that one piece of code uses to communicate with another piece of code. For example, the C runtime library (or any library) has an interface (API), and callers of the library don't need to know about the internal structure of the library to be able to call its services. (There's a pretty good book called "C Interfaces and Implementations" that talks about how to write reusable code in C.)
Classes are also possible to implement in C. A class is pretty much a data structure with a bunch of functions (the methods) that manipulate its data. In C, this can be represented by a structure and bunch of function pointers. The "constructor" function calls malloc() to create an instance of the class, sets its member variables from its parameters and returns a pointer to it. (Implementing inheritance is a bit tricky.)
To be able effectively split development tasks across a team, the same rules apply as in any other language: implement functionality behind well-defined APIs so that one part of the code can be used by another without having to know the details of how it works.
⬐ ectoplasmYou don't need function pointers without inheritance, just take an instance pointer as the first parameter to each class member function.
K&R is more of a reference, I'd suggest this instead:
"C Interfaces and Implementations" by David R. Hanson http://www.amazon.com/Interfaces-Implementations-Techniques-...
I like to recommend C Interfaces & Implementations
It uses Donald Knuth's literate programming which takes getting used to, however, it's a great case study of how to make a good library.
There is a new book on "21st Century C" which I haven't read. It has mixed reviews, however.
two things come to mind.
first is the classic Hanson book "C Interfaces and Implementations", http://www.amazon.com/Interfaces-Implementations-Techniques-... while you may not be coding in C the basic paradigms do carry over.
second is use the API a couple of times and you'll see natural cleavage points.
i generally develop APIs on paper first, which also helps me ensure consistency that is absent when i develop them too quickly or organically. i keep in mind my goals, i document as much as possible, and i try and stick to a paradigm.
hope that helps. i've written APIs used in internal services and applications but never externally, publicly available. i'm no expert but that's how i start.
I am confused by the implication of this codeStack objects are created with "$" so these are on the stack and then placed into the Table? So if this was in a function and the function returned, the Table (lets assume it was global) would now be pointing to destroyed stack variables? Is that the correct interpretation?
var prices = new(Table, String, Int); put(prices, $(String, "Apple"), $(Int, 12));
Is this all done with header files and the preprocessor? It looks like that is the case - if so, I am impressed at the dances you got it to do ;) Also, have you read http://www.amazon.com/Interfaces-Implementations-Techniques-... which does some "Object Orientation" in C tricks?
⬐ MetallicCloudI'm just guessing here, but I assume the variables are created on the stack, then copied into the table object, rather than references being passed to the table. So when the function would end, the original variables would be destroyed, but the copies would remain.⬐ orangeduckThis is correct. "Table" is a datatype which copies the values into the table, while "Dict" is a data type that holds references to the objects. The same semantics hold for "Array" and "List".
Although not perfect this was probably the best way I could have designed such structures. There is some info in the header files as to how to use them.
C Interfaces and Implementations: Techniques for Creating Reusable Software is the best thing I've seen on the topic, personally. http://www.amazon.com/Interfaces-Implementations-Techniques-...
If you like this article, the book C Interfaces and Implementations, goes into this exact technique in great detail, along with many other useful ones.
I picked it up after tptacek recommended it here on HN, and it's definitely worth every penny if you want to do any C programming on a reasonably sized project.
There's also a much cleaner way to have interfaces and implementations in C, without relying on macro hackery.
Why, there's even a whole book on that: http://www.amazon.com/Interfaces-Implementations-Techniques-...
Like Norvig's Paradigms of Artificial Intelligence: Case Studies in Common Lisp and Joshua Bloch's Effective Java, it's one of those books which despite having a specific programming language in the title, is really about programming in general.
⬐ scalywebThis is one of the last books that I'm still hoping will make it to a digital format somehow. I just can't see ordering a new paper copy again.⬐ tptacekThis is my favorite C book ever, I recommend it wholeheartedly, and it recommends voidstars. =)⬐ nkurzRespectful of you but not of the book, I have to ask: what do you like about it? My initial reactions were very negative (http://news.ycombinator.com/item?id=1705332). I love K&R, but recoiled in horror at every page I managed to read of this book.
I've written entire macro-based systems similar to those recommended by the author here, and find them very useful. Void pointers are great where they can be used, but I love the efficiency and clarity of the generated code approach.⬐ tptacek⬐ loewenskindI found your objections to this book pedantic.
For instance, in a chapter on string atoms (symbols) --- a concept which virtually no C program in the world takes advantage of, despite the centrality of the concept to Lisp, Python, and Ruby --- and this is the first chapter in the book --- you were shocked by his use of a 43 byte string to hold a number string... because someone might be using that code on a 192 bit machine?
You missed the forest for the trees. If you don't want your code tainted by the number 43, don't write that code. The point of the book is how you structure your code, divide it into subsystems, and present coherent interfaces to the rest of your program.⬐ nkurzI'm not bothered by the idea of a fixed length for strings, rather the explanation that it is best to use the number 43 instead of a named constant (MAX_STRING_LEN) to avoid namespace pollution. If the first paragraph I quoted had been standalone, or better as a short comment, I would have been in full approval.
Anyway, I appreciate your response. It's good try to appreciate what others see that I do not. Yes, if you ignore the details of the code and the explanations, there are some good parts. If you look _only_ at the big picture, it's probably a fine book. And I love his clearly prefixed naming conventions. But I think you'd do a lot better reading something like the SQLite source code rather than this book if you want to see examples of good C.
I guess I have to ask: do you feel that chapter 4 on using setjmp() and longjmp() plus some brittle macros for error handling is also good for learners? I thought it was technically very clear but about 40 years out of date as to good practice. Is this a forest or a tree?As I recall, Meyer also recommends voidstars for generic collection implementations to deal with template bloat.⬐ strlenTo those who don't yet have it on their shelves, source is available here:
I may be using the word 'modern' a bit liberally here, but these are all more recent than K&R at least. 'C A Reference Manual' I think is what a lot of people really want out of a C book and 'Expert C'/'C Traps and Pitfalls' both help with all of the less intuitive parts of the language that you don't really get out of K&R.
C A Reference Manual http://www.amazon.com/Reference-Manual-Samuel-P-Harbison/dp/...
C Interfaces and Implementations http://www.amazon.com/Interfaces-Implementations-Techniques-...
C Traps and Pitfalls http://www.amazon.com/C-Traps-Pitfalls-Andrew-Koenig/dp/0201...
C Interfaces and Implementations is really good: http://www.amazon.com/Interfaces-Implementations-Techniques-...
⬐ nkurzDifferent books work for different folks, and lots of people seem to love this one. I however love C and found this book to be an abomination. K&R is brilliant. Given an opportunity, I would eradicate this book from the face of the earth lamenting only the damage it has already done.
Examples provided here: http://news.ycombinator.com/item?id=1705332
I would recommend David R. Hanson's book C Interfaces and Implementations. It is an extremely well documented library and shows you how to design APIs properly.
⬐ mhdI'd second that. Beyond just getting a good code base, it's quite likely that you get some good ideas for APIs and algorithms.
Beyond that, Tcl/Tk is a large-ish codebase that's still quite manageable, especially considering its age and the many rewrites.
For a more idisyncratic view, I once went through Rob Pike's sam editor. No header guards, sparse comments, short variable and function names. But you could still figure out what's going on without any problems. That was the old portable sam, don't know if the current plan9port one is still that good.⬐ nkurzBased on the recommendations here, I just got this book by interlibrary loan. I haven't read much of it yet, but I'm glad I didn't buy it sight unseen. It's an understatement to say does not meet the expectations I had for it. Perhaps one could develop a good course around it, and I'm sure there are good things an experienced coder could gleam from it, but as a standalone text for a beginner I think it would do more damage than good.
I thought at first that the code samples he was giving were examples of "what not to do", and then was astonished to find him defending them in the text. From page 36, after some horrendous code for Atom_int() page 35:
"When the conversion is done, s points to the desired string, and this string has &str - s characters. str has 43 characters, which is enough to hold the decimal representation of any integer on any conceivable machine. Suppose, for instance, that longs are 128 bits. The string representation of any 128-bit signed integer in octal - base 8 - fits in 128/3 + 1 = 43 characters. The decimal representation can take no more digits than the octal representation, so 43 characters are enough.
The 43 in the definition of str is an example of a 'magic number,' and it's usually better style to define a symbolic name for such values to ensure that the same value is used everywhere. Here, however, the value appears only once, and sizeof is used whenever the value is used. Defining a symbolic name might make the code easier to read, but it will also make the code longer and clutter the name space. In this book, a symbolic name is defined only when the value appears more than once, or when it is part of an interface."
I'm glad to see his priorities presented in such a clear manner. If you feel that your current code is too readable at the expense of "name space clutter", this might be a good book for you. But otherwise, just say no!
ps. In case this example didn't convince you, the following chapter on using setjmp() and longjmp() to roll your own macros for exception handling might be worth glancing at in the online version before you confirm your purchase.