8 ms·
On becoming an expert C programmer
- informatimago 12y agoNot mentionned, about being an expert C programmer, is knowing the pitfalls of C, (cf. undefined behaviors), and reading and knowing the ANSI C standard. Of course, just knowing the language in and out is not enough, you also have to be a good programmer in general (algorithms, "design patterns", software architecture, software engineering, etc). But writing C code without undefined behavior, and avoiding its numerous pitfalls is absolutely necessary.
- cbd1984 12y agoIf you want to become an expert C programmer, you have to know C As She Is Spoke: Compiler quirks, inclusive of bugs and non-standard enhancements, which can either trip you up or give you a lot more expressiveness, if you're tasteful about where and when you use them. For example, the GNU C typeof() operator makes certain macros a lot cleaner, but it's nowhere in the actual standard. I'm sure other compilers have similar extensions.
- vadivlkumar 12y agooperating system principles and quirks also equally important when you want a expert C programmer.
- humanrebar 12y ago> But writing C code without undefined behavior, and avoiding its numerous pitfalls is absolutely necessary. I rarely (as in unicorns) see C code that consistently checks for unsigned integer overflow. Or signed integer overflow for that matter, but that's defined behavior. Point being, I also encourage people to avoid undefined behavior, but whether and how one does that has subtleties in practice.
- FreeFull 12y agoUnsigned overflow is defined, signed overflow isn't.
- barrkel 12y agoSigned overflow is undefined, unsigned overflow is defined. But I agree with you. Not enough people take integer overflow seriously. Unsigned underflow, perfectly well defined behaviour, is actually a worse problem in practice, IMO. I think too many C programers think about unsigned types like they're a bounded type, e.g. they think "this variable can never be negative, therefore I'll give it an unsigned type". But unsigned types have a cliff of surprising behaviour right where they're commonly used - most integer values in programs are low. Whereas you really need to work on a signed value to get it to overflow.
- Htsthbjig 12y ago"Not mentionned, about being an expert C programmer, is knowing the pitfalls of C, (cf. undefined behaviors)" I am an expert in C, I had been decades writing on it and other languages, and managing teams of coders. We created a company that used it a lot. I can't understand what undefined behaviors C has, because it is the most simple and defined language I do know of. I have lots of experience writing assembler,fortran, Lisp, c++, python, objective C and also use C#, java, javascript and other web languages and functional languages from time to time. c++, java could be extremely undefined because the behavior depends on conventions, committees and implementations. E.g we had to change some code because of different compilers interpretation of the standars. But c? c is basically portable assembler. If you understand how computers work it is extremely reliable bar none. We have ported years of work of dozen programmers in one day. With c++ and "write once, run everywhere marketing" java we spent months. It was also terribly frustrating for the team. Fontforge author had a similar experience writing c++ compilers and that experience was so traumatic the interface of Fontforge is so ugly as he does not want to use c++ with a ten foot pole. We try to avoid pitfalls more in high level languages because the programmer has the ability to write code without understanding what is really happening in the processor, or even in the program. Recipe programmers population is growing a lot this days.
- mahkoh 12y ago>If you understand how computers work it is extremely reliable bar none. On my processor, INT64_MAX + 1 will be INT64_MIN, a negative value. But the compiler is free to turn for (int64_t i = 1; i > 0; i++) { f(i); } into an infinite loop. Understanding how the computer works without reading about undefined behavior will make you fall into these kinds of traps.
- maxlybbert 12y agoIt appears people are still writing C without appreciating the fact that "undefined behavior" means more than "unpredictable," or "might crash." A lot more: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html http://blog.llvm.org/2011/05/what-every-c-programmer-should-... .
- dkarapetyan 12y agoThis answer (http://programmers.stackexchange.com/a/229245/7146 http://programmers.stackexchange.com/a/229245/7146) is about managing code complexity but the lesson applies equally as well to becoming a better programmer with any language.
- hackerboos 12y agoWhenever I've looked at an open source C programs, they go well beyond what I've learned in K&R. Learning C these days means mastering Make, autotools, macros, POSIX and Glib. Knowing these is the difference between your contrived linked-list example and creating software that can actually be deployed and is useful.
- wlkr 12y agoYou make an excellent point. Perhaps more so than with other languages, getting to grips with making C actually useful relies a lot on quite extensive knowledge of the build environment.
- swartkrans 12y agoYou also have to know about how computers work, how they represent numbers, how and where they store memory, how computers process information, you have to know about interrupts low level os stuff, networking protocols, physical hardware limitations, debugging low level byzantine failures. You have to know a lot more than just C syntax. I haven't even mentioned computer science, best practices, working with others, architecture and UI topics.
- bluetomcat 12y agoIt's not only the build environment. Mastering C goes way beyond the superficial level of just learning the language and the libraries. Being a very thin abstraction over the machine, you will inevitably encounter some quirks which can only be explained from the perspective of a compiler writer or a hardware designer. Also, POSIX is not just another library, it's the interface between your program and the operating system. Knowing what to call and how to call it ultimately requires a good foundation in OS theory.
- J_Darnley 12y agoHow is knowing useful libraries for C any different to knowing useful library for other languages? Perl (about the only other language I have any experience with) seems to be dependant on modules which you struggle to compile through cpan.
- malkia 12y agoThere is plenty of C code to look and learn: Linux, PostgreSQL, lua & luajit, sqlite, redis, cairo, nanomsg, libuv, etc. etc
- musername 12y agoId's Quake and Doom sources are a classic in this matter. I looked a bit at wsw, a fork of Quake 2. Now, my code is full of structs with function pointers. It's like I just internalized the more elaborate syntax and now it's all Hammers and Nails. I mean, function pointers to functions returning function pointers, for example. typedef int (*foo) (); foo * bar (); foo * p = bar; not rocket science, but ambiguous at first sight when compressed to one line. I hope that kind of syntax is as complicated as it get's, because I'd like to think C semantics aren't really difficult. That is until implementing customized data types on top. As mentioned in another comment, learning the toolchain is just as important and it's not without reason, that Don Knut takes forever writing about compiler design. Never mind the ventures into the algorithmic side of things.
- kabdib 12y agoThere's nothing magic about learning C versus any other language. - Read an authoritative source (K&R is good; there are better ones) - Read a bunch of good code (I mostly read tools and kernel sources) - Write crappy code and get better Generally I want to write 10K lines of code in a new language before I probably don't suck at it. Varies on the language and paradigm, going to C++ from C took like five years (figuring out OOP, and painful lessons on what to avoid in C++), and apparently I'm never going to understand Haskell.
- emotionalcode 12y ago> and apparently I'm never going to understand Haskell I found this introduction to the concepts of functional programming (functional composition) to be useful: https://www.youtube.com/watch?v=ZhuHCtR3xq8 https://www.youtube.com/watch?v=ZhuHCtR3xq8 Otherwise, it's just a different way of thinking about problems. Instead of building things structurally as an object of objects, and then creating functions that relate, transform, or describe the relationships between the object structures (like taking a pixel object, altering it's x coordinate, and returning the new pixel object with only the x coordinate altered), one has functions that can be composed with other functions to produce more complex object structures. A single base unit with a sequence of functional compositions can describe a very fancy, complex unit, with many fancy, complex characteristics. >> Monads have also been explained with a physical metaphor as assembly lines, where a conveyor belt transports data between functional units that transform it one step at a time.[2] They can also be seen as a functional design pattern to build generic types.[3] http://en.wikipedia.org/wiki/Monad_%28functional_programming%29 http://en.wikipedia.org/wiki/Monad_%28functional_programming... Otherwise, it's syntax and semantics, which I generally find annoying, but there's always google and books. http://www.haskellcraft.com/craft3e/Home.html http://www.haskellcraft.com/craft3e/Home.html
- steakejjs 12y agoI really think C is much easier to get good at than other languages. There is no mystery with what's going on in the computer when you learn C, the builtin functions, how big something is, how things work, etc. When you learn higher level languages there is significant mystery in everything. It means you can write a lot of code having no idea what's going on under the hood, which is good. That's the point of a higher level language, but it is certainly something you SHOULD know in order to call yourself an expert. These mysteries are sometimes what causes Good programmers to get hung up on odd edge cases .
- goldenkey 12y agoC is a cakewalk compared to C++ but a lot harder to do right, even when experienced, because of its more low level constructs
- general_failure 12y agoSure. Climbing a mountain is a cakewalk compared to descending an erupting volcano as well. The analogy being that C++ appears to make things simpler (descending) but the destination is filled with peril.
- xxcode 12y agoThe article advises learning to play music because a lot of good programmers play music. A lot of programmers are also white. Please become white if you can.
- vezzy-fnord 12y agoNot a valid comparison at all. One is a learned skill, the other is an innate phenotype.
- V-2 12y agoThat's true, but the point is that this correlation could be pure coincidence, or at least not causative. (If it actually occurs to start with - it would be interesting to create a poll and verify whether most reputed programmers are indeed more musical than general population.) Many programmers have stereotypical geek interests like RPG, Star Wars etc. but it doesn't mean that these contribute to their programming skills in any way. Being socially awkward doesn't make you Sheldon Cooper :)
- rdc12 12y agoExcept there is a large body of research which shows the effect of music on cognitive ability to support the assertion
- vezzy-fnord 12y agoFreecode is now frozen, but you may want to check out its informal successor Freshcode: http://freshcode.club/ http://freshcode.club/
- bithush 12y agoC is still my favourite language. Sure it has issues but it works how my brain works or is it my brain works how C works? Either way it just makes sense to me.
- greyman 12y agoIn my experience, one of the easiest ways is to just get employed by a company, where coding is done in C. You will have to code in that language a lot and the colleagues can help you. I also learned a few languages myself in my spare time (PHP, Python), but that is not nearly as effective. If you want to really be an expert on C (or in anything imho), you just have to do it fulltime.
- jfaucett 12y agoFor me c is kind of a wierd language. Wierd in that the language itself is incredibly simple, I think anyone could learn c syntax and usage in about 2 days max. But I think where most people get hung up with on c are the concepts, you do need to know about compiling and linking, static vs dynamic libs, lots of details about how computer architecture / memory works, and to get anything done you need know POSIX and the concepts behind any libraries you use. Its not like ruby or other dynamic languages where you could basically have no idea how HTTP works and still write a webapp.
- claren 12y agoThe development of a (good) web-server in pure python likely still requires knowledge of language internals. If depending on libraries, it just depends on the libraries. Web frameworks with "Batteries included" seem rather rare on the C shore, though, maybe because statically compiled languages are in general not used as frequently in web-development. Therefor it's an unfair comparison. To leverage C's power, libraries should also tend to stay general enough, too, no? Most compilers or interpreters are complicated under the hood. Fixing a bug in the compiler to get your code working (and submitting a patch), that's mastery.
- 101914 12y ago"DBell is one of the best programmers on the planet." How would one verify this? I tried a couple of his sample C programs. One of them was one source and one header file and compiled easily and quickly. A+. But then I looked at what the program did and realized I had written several iterations of the same utility myself years ago, using only the shell, sed, tr and ed or vi. I guess maybe his point of writing this in C is that he envisions a system that lacks those programs? Then I tried another sample, which was a little more complex. It failed to compile. Looks like he assumed Linux but failed to state the program is not portable. F. I am always on the lookout for truly great C programmers. Is DBell really as good as Noll says?
- eplanit 12y ago"It is somewhat easy to write a program that works. It requires practice and effort to write code that you can maintain and support." Truer words were never spoken.
- Animats 12y agoYou're an expert C programmer when your C program has enough users that its buffer overflows get CERT advisories from Homeland Security.
- V-2 12y agoLook at some of DBell's code: http://www.tip.net.au/~dbell/ http://www.isthe.com/chongo/tech/comp/calc/index.html Learn from it. DBell is one of the best programmers on the planet. I have nothing against Mr DBell, whom I don't know, but... don't learn from it, please. Weather 1.9 - Java application to plot weather observations from the Australian Government's Bureau of Meteorology (BOM) web site. I did look at it. Controller.java is over 1200 lines long. Don't learn from people who create classes that big (aka God objects). SunriseSunset.java contains nearly 100 lines of commented out code. That's another bad practice. What's more, it consists mostly of a main method commented as "Simple main to test the class". This is a so-called poor man's unit test, it doesn't use assertions, it just prints some results out to be verified by the programmer manually. Which is another antipattern. His FileInfo.java (part of his FileSelection 2.0) contains tautological comments like: // // Get the suffix path. // String suffixPath = fullPath.substring(prefixPath.length()); Gee, you don't say. Redundant comments, another antipattern. isDirectoryEmpty (in the same file) happily ignores an exception: boolean isEmpty = true; try { stream = Files.newDirectoryStream(directoryPath); for (Path path : stream) { String name = path.getFileName().toString(); if (!name.equals(".") && !name.equals("..")) { isEmpty = false; break; } } stream.close(); stream = null; } catch (IOException e) { } finally { Utils.safeClose(stream); } return isEmpty; Meaning that if an IOException occurs (for whatever reason), the method will tell you that the directory is empty, even if that's not true. Setting stream to null after closing it makes no sense whatsoever (it's a local variable, it's not going to survive exiting the method). Closing it in the try block makes no sense to me either, because Utils.safeClose is going to execute either way; that's how the finally clause works. It looks like the author assumed that finally only executes if an exception happens. No, it is run in either case. So, what's the point of closing the stream twice? And if it does serve some purpose, now that would require leaving a comment, because it's totally unobvious. Not "getting the suffix path", which is blatantly obvious. I could go on. This is poor quality code, I'm hardly a great programmer (working on it!), but it's not up to my production standards. If the man is "one of the best programmers on the planet", the planet can't be Earth.
- bluetomcat 12y ago
- neduma 12y ago> Always, always, always write code as if it will last 30 years. Well said. But if i do 'git blame' and see a code is like 30 years old. First thing to come to my mind is it must me some kind crappy old legacy code I know it is wrong. It is substance that matters. But lately somehow i programmed to myself to like newer code then older code. I need to step out that misconception.