20 ms·
The descent to C
- warmwaffles 13y agoI love C. It wasn't my first language to jump in to, but it was eye opening to see the power of pointers and low level operations. Java just couldn't get me close enough to the system.
- benched 13y agoThis looks like a pretty good summary. The stylistic way it's written as if about a 'foreign' language sure makes me feel old though. Twenty years ago, this was completely normal. When I went to work, the code was this. This is what there was. It wasn't "low level" or esoteric - just a nice language to feed through the compiler to get executable code.
- adinb 13y agoYes! It makes me feel like my entire CS education (early 90's) was one long hazing ritual with grad students and professors laughing at us in the backroom...while we're busy trying to fix one-off indirect pointer errors.
- laichzeit0 13y agovalgrind / gdb should have made this painless, especially for small self-contained uni projects :) I remember being a teaching assistant for some C++ courses while being a student and the "Are you a wizard?" expression on the undergrads faces when I'd recompile their segfaulting app with debug, run gdb and tell them exacly which line was causing the problem.
- sehugg 13y agoI went straight from Apple BASIC, FORTH, and 6502 assembler to Turbo Pascal, and C seemed esoteric to me at first, and even unneccessary -- compared to Turbo Pascal that is. Then when DOOM was released compiled with Watcom C, I realized this 32-bit C compiler thing was a big deal.
- pjmlp 13y agoWhat baffles me is that this is the type of coding young developers associate with C and C++, whereas we had lots of options to choose from, as you well list.
- AlexanderDhoore 13y agoSome time ago, I did some Free Pascal programming and was surprised that it was much nicer than C. But C won the war because of Unix OSs, not because it's such a good language.
- oinksoft 13y agoCustomers have been demanding books about the WWW, so book stores have been flooded with titles on whichever garbage-collected language is hot for web development at the moment. Since the dot-com boom, your average novice trying to put food on the table has been unlikely to pick the C title off the shelf when the Java or Ruby book is far more likely to fetch a job in six months. Until recently, the perceived cost of C/C++ tools for mainstream platforms also made the simple Java downloads far more attractive. Just getting started learning to program myself in 2000, I remember Perl and Java were the things, and PHP a year later. I had to go out of my way later on on to learn C.
- philbarr 13y agoYes. In fact in my local Waterstones, where supposedly pay a little more so that the knowledgeable staff can help you, I recently saw a sign for books: "C, C+, C++".
- pjscott 13y agoI remember when peeking and poking were totally normal things that people did. The world is more convenient now, I suppose.
- betterunix 13y ago"the length of the array isn't stored in memory anywhere" This is probably not true. For arrays on the heap, the size (or an approximation e.g. number of pages the array spans) would have to be stored somewhere in order for the array to be deallocated. For arrays on the stack, the size is either known at compile time, or else it was at least available when the array was allocated and could be kept in the stack frame (and in many cases would be kept in the frame anyway). Not only that, but the common pattern of passing a pointer to an array and its length as arguments to a function implies that most of the time C programmers keep the length of the array stored somewhere. You are really talking about niche cases where the length of the array is truly and inherently unavailable. Really this has more to do with the fact that C is meant to do as little as possible for programmers -- it is supposed to be "close to the machine."
- benched 13y agoThat's a lot of words just to be pedantic. What a heap allocator does in its bookkeeping is not necessarily "storing the length of the array" - and whatever it does isn't sensibly available to the running program. Yes, the size of a static array is known at compile time, but it's length is still not available to the running program unless the programmer explicitly arranges for it to be.
- rayiner 13y agoIf you're programming in C, it's not unreasonable to be pedantic about stuff like this. :D
- jevinskie 13y agoI looked into this. It seems that OS X provides malloc_size. [0] I wonder if other *BSDs have it or if it is a XNUism. I can't find an equivalent for glibc, which I find disappointing given how immense glibc is. Even if it is potentially a "shoot yourself in the foot" feature, I can see many judicious uses of it. And even with such a size query, it is still obviously not something nice and built into the language. But C folks are used to that! =P [0]: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/malloc_size.3.html https://developer.apple.com/library/mac/documentation/Darwin...
- michaelhoffman 13y ago> If you've used Java or Python, you'll probably be familiar with the idea that some types of data behave differently from others when you assign them from one variable to another. If you write an assignment such as ‘a = b’ where a and b are integers, then you get two independent copies of the same integer: after the assignment, modifying a does not also cause b to change its value. This is incorrect when it comes to Python. a and b will be two different names for the same integer object, which is stored in a single memory location. The difference is that Python guarantees that integers are immutable.
- jffry 13y agoArguably, to a user of the language, these are imperceptible from independent. Changing one cannot change the other (except perhaps through some exotic double-underscore-prefixed function with which my vague knowledge of Python is unfamiliar)
- jpace121 13y agoYou definitely notice the difference when dealing with mutable types in python, like lists. >> a = [1,2,3] >> b = a >> a.append(4) >> b #[1,2,3,4] This is one of the things that throws off many beginners, and is an easy trap to fall into, not exotic at all.
- beambot 13y agoOP literally says this in the next sentence: > But if a and b are both variables of the same Java class type, or Python lists, then after the assignment they refer to the same underlying object, so that if you make a change to a (e.g. by calling a class method on it, or appending an item to the list) then you see the same difference when you look at b.
- rcxdude 13y agoHis point is that there isn't a difference in python: in both cases you're just changing labels, but in the case of integers they're pointing to immutable objects.
- ChuckMcM 13y agoShhhhhh! If you let them know how fun it is then everyone will want to be C programmers :-) I got to use my crufty C knowledge to useful effect when I discovered that there is no standard system reset on Cortex M chips. That lead me to trying to call "reset_handler" (basically the function that kicks off things at startup) which I couldn't do inside an ISR because lo and behold there is "magic" in isrs, they are done in "Handler" mode versus "Thread" mode and jumping to thread mode code is just wrong apparently. C hackery to the rescue, hey the stack frame is standard, make a pointer to the first variable in the function walk backwards on the stack to return address, change it to be the function that should run next, and return. Voila, system reset. The whole time I am going "Really? I have to look under your covers just to make you do something anyone might want to do?" As a respondent to one of my questions put it "ARM is a mixture of clever ideas intermixed with a healthy dose of WTF?"
- mooreds 13y agoAs someone who swore off c after a college class and an experience with perl (three cheers for memory management), this was a great intro article to the idioms of c.
- jevinskie 13y agoI first learned "true" programming with Perl. My next language was C to learn how to program microcontrollers. Incidentally, they remain my two favorite languages even after Python, C++, Java, Tcl, shell, LISP, and multitudes of assemblies. I feel these two languages cover most of my uses. I just wish the built-in XS Perl<>C integration was simpler. I need to look into some CPAN modules for a more ctypes-like interface. Better yet, it should use libclang to autogenerate bindings!
- bch 13y agoSince you mention you have Tcl experience, you may want to (re?)explore the Tcl/C relationship. An absolute joy to work with. Also, re: bindings, you may be interested in the SWIG interface generator: http://www.swig.org http://www.swig.org
- rayiner 13y agoThe article is good, but I disagree with this part: "To a large extent, the answer is: C is that way because reality is that way. C is a low-level language, which means that the way things are done in C is very similar to the way they're done by the computer itself. If you were writing machine code, you'd find that most of the discussion above was just as true as it is in C: strings really are very difficult to handle efficiently (and high-level languages only hide that difficulty, they don't remove it), pointer dereferences are always prone to that kind of problem if you don't either code defensively or avoid making any mistakes, and so on." Not really, and not quite. A lot of the complexity of C when it comes to handling strings and pointers is the result of not having garbage collection. But it does have malloc()/free(), and that's not really any more fundamental or closer to the machine than a garbage collector. A simple garbage collector isn't really any more complicated than a simple manual heap implementation. And C's computational model is a vast simplification of "reality." "Reality" is a machine that can do 3-4 instructions and 1-2 loads per clock cycle, with a hierarchical memory structure that has several levels with different sizes and performance characteristics, that can handle requests out of order and uses elaborate protocols for cache coherence on multiprocessor machines. C presents a simple "big array of bytes" memory model that totally abstracts all that complexity. And machines go to great lengths to maintain that fiction.
- agumonkey 13y agoI wonder if someone will (or already has) design a low-level language which is async and cache-hierarchy aware.
- collingreene 13y agoThis is really great. I have found myself saying some of these same things when explaining things. Going to keep this in my pocket to use in the future. Thanks!
- Tegran 13y ago> And there's no simple excuse for the preprocessor; I don't know exactly why that exists, but my guess is that back in the 1970s it was an easy way to get at least an approximation to several desirable language features without having to complicate the actual compiler. Clearly this guy has never had to deal with a large, complicated code base in C. Dismissing the preprocessor as a crutch for a weak compiler shows a significant ignorance about the useful capabilities that it brings.
- Guthur 13y agoI doubt he meant that it was not useful, rather that the usefulness might have been better served as a function of the compiler rather than some disconnected transformation tool. Of course this thought process would eventual bring you down the road of macros systems such as those in Lisps, but that's going to be more difficult with a language lacking homoiconicity of code and data.
- zurn 13y agoIt's just unfairly easy in Lisp :) There are macros in many non-homoiconinc languages (eg. Rust, Dylan), and there are add-ons for several of the languages lacking them (eg. SweetJS for Javascript, MacroPy for Python).
- i_c_b 13y agoI assume when he says "no simple excuse", it's more pointing to the massive problems that the mere existence of the macro pre-processor introduces for reasoning about the text of any C or C++ program, for programmers, tools, and compilers. I've worked in a code base where, tucked away in a shared header file somewhere up the include chain, a programmer had added the line #define private public (because he wanted to do a bunch of reflection techniques on some C++ code, IIRC, and the private keyword was getting in his way) Now regardless of whether that's a good idea, if you are reading C or C++ code, you always have to be aware, for any line of code you read, of the possibility that someone has done such a thing. Hopefully not, but unless you have scanned every line of every include file included in your current context recently, as well as every line of code preceding the current one in the file you're reading, you just can't know. Clearly this makes giant headaches for compliation and tools, as well. So yeah, of course every mid to large C / C++ program uses the macro pre-processor extensively. You can do useful things with it, and there's no way to turn it off and not use it, anyway, given the way includes work in C / C++, so you might as well take advantage of it. But it's not an accident that more recent languages have dropped that particular feature.
- lstamour 13y agoKnowing a bit of C but often programming in just about any other language, I was recently inspired to work with lower-level languages like C++ thanks to a bunch of talks from Microsoft's Going Native 2013. Specifically Bjarne Stroustrup's The Essence of C++: With Examples in C++84, C++98, C++11, and C++14 -- video and slides at http://channel9.msdn.com/Events/GoingNative/2013/Opening-Keynote-Bjarne-Stroustrup http://channel9.msdn.com/Events/GoingNative/2013/Opening-Key... C++ really has changed and is changing from what I learned back in university. It's quite exciting. They seem to be standardising and implementing in C++ compilers the way HTML5 is now a living standard with test implementations in browsers. See also: http://channel9.msdn.com/Events/GoingNative/2013/Keynote-Herb-Sutter-One-Cpp http://channel9.msdn.com/Events/GoingNative/2013/Keynote-Her...
- NigelTufnel 13y agoThere is a great moment in Stroustrup's talk when he shows a short error message in ConceptGcc and the audience applauds. It seems that Stroustroup was suprised by the applauses.
- lstamour 13y agoHe's a university prof. When's the last time they ever heard applause? ;-) Really, in part, I think it was because he was trying to finish a thought and was going to summarize the feature again in two slides. But yeah, I'd have cheered. It felt like C++ the Steve Jobs keynote, in a way. All the good parts, right in front of you, shipping "soon".
- lstamour 13y agoFor the Google index, I'd also like to note that LLVM 3.4 released three weeks ago, has support for C++14 in Clang. Incidentally it also mimics Visual C++'s compiler from Microsoft in Visual Studio. I'd expect it to ship with an Xcode 5.1 alongside iOS 7.1. Now that I think about it, I should run to Apple's developer site and see if that's true. :) Edit: Xcode 5.1 beta 4 ships with Apple LLVM version 5.1 (clang-503.0.9) (based on LLVM 3.4svn) according to Google searches. So I guess that's a yes. I'm off to try it now. :)
- Chromozon 13y agoC is a great language- it let's you get down and dirty with the computer. However, the one huge downside to programming in C is having to deal with strings. Let's face it, C strings are absolutely terrible. For such an important feature, the string implementation of null terminated char* is just miserable to work with. See: http://queue.acm.org/detail.cfm?id=2010365 http://queue.acm.org/detail.cfm?id=2010365
- stusmall 13y agoThat is a problem with the stdlib and not so much the language. There is nothing stopping you from creating a more robust string implementation that stores size and does bounds checking for some operations(You can't easily/safely enforce anything like string immutablity at the language level... unless anyone out there can think of a way). I've seen it before, but not often. Usually the C code I'm working on does very little string manipulation and speed/size matters.
- i_c_b 13y agoWell, to be fair, strings are much nicer to work with when you have a suitable overload for '+', and that very much is a problem with C the language. Same goes for 3d vectors in C as well.
- theseoafs 13y agoThat's your opinion. I (and many other C programmers) find it refreshing that when I see a "+", a couple numbers are going to be added together. Nothing else could possibly happen, and I don't have to cross-reference the types of the operands to figure out whether a method in some far-off source file is going to be called.
- i_c_b 13y agoC is willing to hide a lot of numeric type casting details about doubles vs floats vs unsigned ints vs chars behind the magic of the "+" character, so maybe you're willing to endure a lot more type-dependent compiler magic than you're letting on here, despite so graciously speaking for many other C programmers. In fact, "p+1" might very well mean "p+4" if p is an int. Or maybe it means "p+32" if p is a FILE (on my compiler). Or maybe it means... Wow! Wait a second! That seems pretty type dependent to me, come to think of it! But that's just my opinion.
- Trevor-C-Hunt 13y agoOh come on. I know you hipsters love vintage, but please stay away from C. You'll put someone's eye out.
- nathanb 13y agoProfessional C programmer here... The points are great and this is generally a good primer for someone who wants to understand the C mindset. The bit at the end is a bit off, though. It feels like the author is saying "yeah, C is weird and crufty for historical reasons and some people just use it because they're backward like that". Yeah, I write kernel drivers, but I also just plain like using C, for the same reason that I like driving a manual transmission and usually disable the safety features on stuff: C tries really hard to not get in your way. I enjoy programming in Ruby and mostly enjoy programming in Javascript. But there are times when I think "this is an unnecessary copy...this is inefficient...I wouldn't have to do this if I were writing in C". (There are also times where I think "this one line of code would be over 100 lines of C", but we won't get into that right now...).
- adrianm 13y agoI experienced the inner monologue you describe for several years. It haunted my dreams when working with Ruby. But one day a rhetorical thought suddenly dawned on me that has since changed my perspective quite dramatically... "...if I'm being incessantly bothered by what I perceive as the nagging inefficiencies of some programming language's implementation, maybe I'm not thinking about or relating to programming languages (in the large) in the way I should be..." If all programming languages are merely tools to communicate instructions to a computer, then why is human language not merely viewed by everyone as a means to an end as well? Surely, most would agree that language is more than simply an ends to a mean, and that language does far more than simply transmit information between parties. If efficiency, lack of ambiguity, etc., were the paramount goals of human language, surely formal logic, or perhaps even a programming language for interpersonal communication would be more fitting than natural language! So why do we insist on communicating with each other with what is often such an abstract and ambiguity filled medium? I'll let wikipedia elaborate on my behalf: http://en.wikipedia.org/wiki/Pragmatics http://en.wikipedia.org/wiki/Pragmatics and http://en.wikipedia.org/wiki/Deixis http://en.wikipedia.org/wiki/Deixis http://en.wikipedia.org/wiki/Literature http://en.wikipedia.org/wiki/Literature tldr; it is trivial, even natural for an literate individual with the proper context to understand concepts in language that seemingly transcend the words themselves. These notions would be (and are) exceedingly difficult to formalize, and any formal expression of these ideas would cause exponential growth of the output. Ever try explaining a joke to someone who didn't "get it"? It takes a lot more "space" to convey the same sentiment than to someone who "got it". So what has this crazy rant have to do with anything? Well, aside from revealing I am a complete nerd, it speaks to my approach to software engineering today. We have to let go of the machine if we ever want to really move the state of the art forward. There are an infinitude of expressible ideas, but lacking the proper medium to abstract the expression of these ideas formally (like natural language and our brains do, well, naturally) we will never get a chance to find out what we don't know! "We're doing it wrong" is not exactly the sentiment I'm trying to express, but it's sorta that. Maybe. Hope this comment made any sense. :) It's 4 AM after all.
- zem 13y agoif you're not familiar with simon tatham, do poke around his site [http://www.chiark.greenend.org.uk/~sgtatham/ http://www.chiark.greenend.org.uk/~sgtatham/] - he has an eclectic and delightful assortment of code and writing. probably best known for putty, but the rest of it is a lot of fun to browse through.
- blueblob 13y agoHe should be best known for bsd-games (package name on archlinux, I think ubuntu too). :-) http://www.chiark.greenend.org.uk/~sgtatham/puzzles/ http://www.chiark.greenend.org.uk/~sgtatham/puzzles/ EDIT: oops, the link is for a different package called puzzles on archlinux though he also did make bsd-games (which are text based such as boggle)
- zem 13y agohe wasn't behind bsd-games, which is a collection of old games originally created by various people - see https://github.com/vattam/BSDGames/blob/master/AUTHORS https://github.com/vattam/BSDGames/blob/master/AUTHORS
- wmt 13y agoI was bit bothered that with all the talk about malloc it was never highlighted that not all memory needs to be manually freed: local (stack) variables are quite safe, why it is a common pattern to give pointers of local variables to functions to store their results in. There are some common exceptions for this when you just need to call malloc, but these should be treated as exceptions.
- spikels 13y agoThe article does exactly what it sets out to do: introduce C to programmers used to more modern languages. I started programming in C again a few months ago after a 15 year hiatus and the language I remembered loving seemed strange and tedious. This would have been a great reminder of the many differences that after a while you just take for granted. Something similar would be useful for most languages but just more so for C (or say, FORTRAN). My only quibble would be that while malloc/free are covered many variables are simply automatically aloocated and deallocated on the stack. C's dual approach to memory management is yet another frequent source of confusion.
- Kiro 13y agoI thought Java was on a much lower level than Python. Why is C more low-level?
- alecdbrooks 13y agoWell, did you read the article? It describes manual memory management, which is probably the most obvious reason C is lower level. It also talks about how strings are stored directly as arrays of characters as opposed to objects wrapping character arrays. Finally, C pointers are closer to how the computer operates (they're basically memory addresses) than anything in Python or Java. What constitutes a "low level language" is a matter of perspective, however. From the perspective of writing binary instructions by hand, all three languages are "high level." ;)
- AnimalMuppet 13y agoHeh. My mother did in fact program in binary (well, octal), back in the 1950s. Even assembly is a "high level" language from that perspective.
- crpatino 13y agoManual memory management, mostly. Also, since C is a simpler language, its building blocks map more closely with what actually happens on hardware level (or they used to... back in the 1970's). Then, there's the fact that you do not have direct access to native OS primitives from Java (i.e. system call vs stdlib function), but it has to do more with the run-time environment than the language itself.
- Toenex 13y agoThe Java language is designed to be compiled to a Java Virtual Machine (JVM) which is a software implementation of a computer that doesn't exist (easy there existential freaks, I'm trying to keep this brief). The VM abstracts away the hardware differences between platforms, in theory allowing the Java language greater freedoms. Simple things like endian-ness are no longer a language issue as the VM says all machines are big endian. Compare this to C where the code is compiled to a native format that is very much tied to the hardware/OS platform.
- laichzeit0 13y agoRecently I had to write a program for an embedded Linux router which ran on a MIPS architecture and had a 2MB flash. I only had about 40kb of space to fit the application on. I was able to get a binary that was compiling to more than 1.5mb down to 20kb through using a combination of gcc tricks like separating data and code sections, eliminating unused sections, statically linking some libraries and dynamically linking against others. It once again gave me immense appreciation for having a language and toolchain that can give you this power for those 1% of problems your career might depend on. For amusement, the relevant section of the Makefile I ended up with: LIB_NL_MIPS_STATIC=libs/libnl_mips_static CFLAGS=-Os -I$(LIB_NL_BASE)/include -ffunction-sections -fdata-sections -Wall -Wextra -MD LDFLAGS=-Wl,--gc-sections -L$(LIB_NL_MIPS_STATIC) -Lbuild -Wl,-Bstatic -lmon -lnl-3 -lnl-route-3 -Wl,-Bdynamic -lpthread -lm -lc I'm unsure how many other languages/toolchains give you that sort of flexibility down to the linking level. Also it's self contained and doesn't require some kind of "virtual machine" or interpreter to run it.
- userbinator 13y agoThat makes me wonder why "eliminating unused sections" isn't a default, as it feels like the compiler is doing a lot of unnecessary work if it's generating 1.5M of output that actually has only 20k of useful stuff in it.
- laichzeit0 13y agoIt's only that big because of static linking. Typically you're never statically linking your applications, but in this case it's necessary if you want to use libraries but only want the space-overhead from the code and data you use from the libraries. It reminds me of a quote I read in the book, Expert C Programming: Deep C Secrets (an excellent book on C btw), that read: "Static linking is now functionally obsolete, and should be allowed to rest in peace." I kinda chuckled a bit when I saw.
- uggedal 13y agoIt's far from obselete: http://sta.li/faq http://sta.li/faq
- yason 13y agoI remember when I first learned C. I was 13 and having written assembly for years I finally got a machine that was actually equipped for running a full-blown C compiler. Compiling was slow and the produced code was slow but all I could think of was how easily I could generate [assembly] code with just a few lines of C. Loops, pointers, function calls, conditionals... just like that. Wow. So productive. C felt like writing assembly but with much better vocabulary. C was to assembly language what English was to the caricatured "ughs" of the stone age. I often compared the output of the compiler to what I would've written myself: the output was bloaty, the compiler was obviously not very smart, but it did do what I wanted and the computers had just got fast enough to be able to actually run useful programs written in C without slowing down the user experience. So you couldn't necessarily distinguish a program written in C from a program written in assembly, and you could "cheat" by choosing C instead. That was so exciting! The thing is, however, that since these trivial insights of my youth it turns out that C actually never ran out of juice. I still write C and I'm enjoying it more than ever. In C, I've learned to raise the layers of abstraction when necessary and writing C in a good codebase is surprisingly close to writing something like Python except several dozen times faster and you can build your memory layout and little details the best suitable way you want, in various meaningful contexts. I love doing all the muck that comes with C. String handling, memory management, figuring out the best set of functions on top of which to compose your program, doing the mundane tasks the best way in each case, and never hitting a leaky abstraction like in higher level languages. The thing is, the time I "waste" doing all that pays me back tenfold as I tend to think about the best way to lay out my program while writing the low-level stuff. Because such effort is required there's a slight cost in writing code which makes you think what you want to write in the first place. In Python you shove in stuff into a few lists and dicts, it just works and you will figure out later what was it that you really wanted and clean it up. But often you're wrong because it was so easy in the beginning. In C, I have to think about my data structures first because I don't want to write all that handling again for a different set of approach. And that makes all the difference in code quality. However, I don't think you could impose a similar dynamic on a high-level language. There's something in low-level C that makes your brain tick a slightly different way and how you build your creations in C rather than in other languages reflects that. The OP said it very well: C reflects the reality of what your computer does. And I somehow love it just the way it is. I've worked most of my career in higher level languages but I've never set C aside. It has always been there, even with Python, C++, or some other language. Now I'm writing C again on a regular basis and with my accumulated experience summed into the work it's truly rewarding.
- nadam 13y agoThe article only discusses the 'extremities' (C vs. Python/Java, etc...) when there is an obvious and popular 'compromise': C++, which has most of the discussed advantages of both sides. (Although it has some drawbacks; it is a bit more difficult to master than either C, Java or Python.)
- NAFV_P 13y agoThis goes into more detail on pointers than some tutorials on C++, pointers are bread and butter in C. The article should have given a link to: http://cdecl.org http://cdecl.org The last time I visited that site I ended up crossed-eyed, incontinent and speaking in DEC-PDP8 assembly for several days.
- fit2rule 13y agoWant to have fun learning C? Add Lua to the mix. ;) All the joy and performance of C - wrapped up in a nice little language that lets you Just Get On With It. Plus, anyone who can sort out putting the LuaVM into a new set of libraries, thus creating a Framework, is one step closer to Developer God, in my opinion .. ;)
- acorkery 13y agoI really enjoyed this article. I started out programming in C, then quickly on to Java. I didn't appreciate the language at the time, but with hindsight, the fact that you need to worry about memory allocation and performance means you've a better understanding of what's happening on the underlying system. It should never be taken off CS courses!
- ejk314 13y agoI completely agree. I took one semester of Java then one semester of C when I was first learning to code. I think that extra semester of C gave me a significant advantage over some of the other programmers in my next school because I had a much better understanding of what was going on under the Java straight-jacket.
- helicon 13y agoA great resource for learning C is CS50 on edx: https://www.edx.org/course/harvardx/harvardx-cs50x-introduction-computer-1022 https://www.edx.org/course/harvardx/harvardx-cs50x-introduct...
- rlpb 13y ago> But those aren't the reasons why most C code is in C. Mostly, C is important simply because lots of code was written in it before safer languages gained momentum... I disagree. Certainly in the FLOSS community, I don't think this is true. C is a lowest common denominator. No higher level language has "won". So if you want the functionality in a library you write to be available to the majority, you will need to make it available (ie. provide bindings for) a number of high level languages. The easiest way to do this is to provide a C-level API. This works well because the higher level languages are all implemented in C. This isn't because C is more popular, but because it is a low level language. The easiest way to provide a C-level API is to write the code in C. So: library writers often write implementations in C. There are three alternatives: 1) Independently implement each individual useful piece of functionality in every high level language. This does happen, but more general implementations tend to move quicker, since they have more users (because they support multiple high level languages) and thus more contributors. The number of contributors might dwindle because of the requirement to code in C, but I don't think this has happened to a significant enough extent yet. 2) Implement libraries in a higher level language and then provide bindings to every other popular higher level language. This can be done, but I haven't seen much of it. Higher level languages seem to make it easier to provide bindings to a C-level API rather than APIs written in a different higher level languages. This may be something to do with impedence mismatches in higher level language concepts. 3) A higher level language "wins", and everyone moves to such an ecosystem. This can only happen if other higher level languages lose. I don't think there is any sign of this happening.
- gaius 13y agoThis works well because the higher level languages are all implemented in C Not actually true; there are many high level self-hosted languages, OCaml, Haskell, Forth, Lisp, etc etc. But all these languages generally prioritize having a good C FFI. It is interesting that e.g. Thrift, Protocol Buffers et al don't seem to have made much of an inroad here.
- userbinator 13y agoOcaml's VM is written in C.
- jheriko 13y agointeresting read. one of the later comments is a bit off the mark though: " As a direct result of leaving out all the safety checks that other languages include, C code can run faster" C is fast not just because of missing safety checks but because more generally you don't pay for features you don't use. Things like function calls and reading data are not complicated by run-time type logic for instance - this is very important, its why you can write an Objective-C class which has the same content as a bunch of C functions and the C functions will be (sometimes very significantly) faster. This is one example, but many language features in high level languages suffer from similar performance problems - by being super generic and ultra late binding they can never perform as fast as a clean implementation which knows everything at compile time. If you want dynamic late binding type functionality in C you have to do it yourself...
- gmac 13y agoThe really nice thing about Objective-C, of course, is that you can just dip in and out of plain C as the mood takes you (e.g. where speed matters, or perhaps where you're just doing numerical stuff and C is less verbose). I've come to C via Objective-C, and (like many other commenters here) have found it incredibly satisfying.
- rehack 13y ago>7. There is no convenient string type This the reason, which stops me from going back to C. After coding in Java (mostly) for past 10 years. I wanted to switch back to C or C++. Mainly to save on ton of memory being used which I think is unwarranted. So I experimented with a new service, and coded it in all three C, C++ and Java. When I did this I had not coded in C++ for 10 years, but it did not hurt at all. I could switch back easily with almost no great difficulty. There were some minor inconveniences of foregoing the Eclipse editor. I think, I might have missed Autocomplete the most. But within hours after I started, I was getting my previous feeling of the Vi(m) editor coding of C++ back. And with the benefit of having STL (vectors, strings, etc.) I did not feel much discomfort. But coding the same service in C was painful. And it was mainly because of not being able to basic things on strings easily like copy and concatenate. But thankfully I still managed to do it. And on comparing the three services for latencies and memory usage, I found little difference between C and C++. So eventually that service was deployed in C++ and still runs the same way. This above episode happened about an year back, and recently I am using Go to do a lot of services (new as well as moving some old). Mainly I have been motivated by the promise of an easier C, which it seems to offer. Some services, coded in Go, I have deployed and are already running very well. But even now, I need some more experience on the results side, to have a definitive opinion on whether Go is indeed C with strings lib (and other niceties) for me. Edit: rephrase for clarity
- theseoafs 13y agoDid you use a string library when working in C? C's deficiencies when it comes to string handling are well-known.
- rehack 13y agoSorry for the delay in replying. No I did not, actually. See I was coming back after a while, I had quickly shifted to C++ (after coding briefly in C) in my career, so did not remember using any libraries. I am sure, my task would have been easier if I had used some lib. But my main concern (and goal) was performance and memory usage comparison.
- humanrebar 13y ago
- massysett 13y ago>C is quite different, at a fundamental level, from languages like Java and Python. I suppose, but functional languages are even more different. From Python, the ascent to Lisp or Haskell is much more difficult conceptually than the descent to C.
- fulafel 13y agoI thought lisp pretty easy to approach coming from python once the parens stopped sticking out. lisp is not really a FP language. http://norvig.com/python-lisp.html http://norvig.com/python-lisp.html
- tedchs 13y agoWhat a great explanation. I have been doing some low-level Go programming recently (including implementing the writev syscall), and I think this document would also be useful for Go programmers.
- pjmlp 13y agoMany of the features people nowadays atribute to C, do exist in other impereative languages that compile to native code. But as many used to be in diapers when compilers for those languages were available, they only know C.