I have a strong Java/Groovy background and I've been assigned to a team that maintain quite a big C code base for an administrative software. Some pain points, like dealing with blob in the database or generating reports in PDF and Excel have been externalized to java web service. However, as a Java dev, I'm a bit confused by some aspects of the code:it's verbose (especially when dealing with 'exception')there's a lot of huge methods (many 2000+ lines method)there's no advanced data structures (I miss List, Set and Map a lot) no separation of concern (SQL is joyfully mixed all around the code)As a result I feel that the business is hidden in tons of technical code and my brain, shaped with Object Oriented and a pinch of Functional programming, is not at ease. The good side of the project is that the code is straight forward: there is no framework, no byte code manipulation at runtime, no AOP. And the server can simultaneously answer to 10000+ users with a single machine by using less memory than java needs to spit hello world.I want to learn how to write C code accordingly to commonly accepted modern principles. Is there any commonly accepted principles about how modern C should be written and structured ? Something a bit like the equivalent of the 'Effective Java' book, but for C.Edit at the light of answers and comments:I'll try to adapt my mindset to C code and not try to mirror it to OOP. I've started to scan-read the recommended coding style guides from the comment (The GNU Coding Standards and The Linux Kernel Coding Style). I'll then try to propose this code style to my co-workers.The most difficult part might be to convince co-workers that huge method could be split in smaller parts and that to repeat the same 4 lines of error handling code could be avoided by the help of a method.
Is there any commonly accepted guidelines about how to write modern C?
c;maintenance
I can read from your question the problem isn't that the code is old C but just bad programming. Most of the problems you mentioned like verbosity, huge 2000+ line functions, or no separation of concerns is applicable to any language, C or Java alike.Verbosity was mentioned in context of error handling. You didn't provide an example so I can only remind that error handling code is also code. There is no excuse for repetitive sections of boilerplate code. Factor it out; either to a function or (if it's not worth to create a separate function) do the goto Error; pattern and move the error handling and resource cleanup to an Error: section at the bottom of the function.If passing the error up the call chain seems to be the problem, ask yourself: does the function up there really need to know some little guy down here had a problem? Exception mechanisms built-in a language make it easy to do so, but in general it's better to handle exceptions early (in any language) so that the error condition doesn't pollute the logic of high-level code. And if the function up there really needs to know, there are ways to emulate exceptions with setjmp and longjmp.I think the only really C-related problem mentioned is the lack of standard containers. While Set can in general be replaced with a sorted array and Map (for the most part) with an array of pairs or a struct (if you know the key set before hand, map[key] = value turns into s.key = value), but the fact is there's no dynamic array container in the standard library. In C99 you can at least declare a variable length array on the stack (int array[len]) but you need to calculate len beforehand (usually not hard) and of course you can't return it as any stack-allocated object. Most project end up with writing up their own dynamic array container or adopting an open-source one.On a closing note, I'd like to point out that I've been there. I've been the Java programmer that moved to C++ and pure C. I would like to advise read book X to learn good C but there isn't any just like there isn't any for Java. The way to go forward is to soak up all the intricalities of the language and the standard library; google a lot, read a lot, and code a lot until you start thinking in C. Trying to write things in C as you would in Java is as frustrating as trying to write a sentence in a foreign language with words directly translated from your mother tongue; both you and the reader will cringe. The good news is that learning good programming is slow but learning another language is fast. so if you write decent code in Java, applying the same general common-sense to C will work too.