Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++?

I asked this question of a younger programmer the other day, because it seemed to me, that to HIM, learning C was a rite of passage, and that he was less of a man for not knowing it.

I find macho philosophies in software development both amusing and counter-productive.(If you really want to be macho, become a lisp hacker). My amusement may be personal, but the counter-productivity of using C, when better abstractions (i.e. programming languages) already exist, is real. It creates fiefdoms and priesthoods that are counter-evolutionary and hard to maintain, and leads the death of much software.

Personally, I would rather std::string be pored over by many eyeballs and evolved than change strcpy to _strcpy or strlcpy. Unless I am working for NASA on an embedded device for a satellite, I would rather Moore's law or SMP or DSMP give me the speed I need, than give up productivity to squeeze every last CPU cycle. Developer time is a lot more expensive than hardware (except on satellites and space stations).

Apologies if it is your ambition to work for NASA on embedded devices in space stations, I just think you may as well learn C++. You get most of C, plus some really useful and productive abstractions as well.

If you want speed, learn inter-process communication and the principles of symmetric multi processing. With C++, you also get to abstract away the problems of strcpy and strlen, replace Byzantine function references with class methods, and 35 parameter functions with polymorphism. Best of all, most of the programming world will still think you are manly if you know C++, so you get that too.



Not all of us see C++ as an improvement over C.

Sure, C++ has great advantages, but it also great disadvantages.

I use C for many things not because of "macho", but because C is good enough. I can work around the disadvantages using standard techniques. The result is code that is easily FFI'able from any language, quicker to compile, has a smaller footprint, sane error messages, easily debuggable in gdb, etc.

Also, there are some advantages in the abstractions that C encourages you to use. For example, lack of templates pushed C programmers to discover intrusive data structures, and those are better in many ways than templated containers ala STL.

Another example: "virtual" methods may fail to override a base class method if you make a typo - resulting in potentially cryptic bugs. Using a simple macro in C:

  #define MAKE_VTABLE(prefix)  { prefix##foo, prefix##bar }
I can make vtables that are safer than C++, and require no more boilerplate than C++ code. The compiler will guarantee that I implement all of the required vtable methods.

If I want to get speed via multi-core rather than pure uniprocessor speed, why use C++? I can use Haskell and get much easier and safer parallelism with many other advantages.


Thanks for your reply.

> Not all of us see C++ as an improvement over C.

I know, but you are the first I've encountered to quantify it.

> The result is code that is easily FFI'able from any language

I agree that this is a big advantage for interoperability. While it's possible to build an interface in C++ with 'extern C', it means maintaining two call APIs rather than one. Still I see this as a current limitation of C++ rather than an advantage of C.

> Using a simple macro in C:

Is generally a pain as the macro is expanded at compile time and causes difficulties debugging. Your point about VTABLEs is well taken however and I have encountered subtle bugs with virtual member functions in C++.

> If I want to get speed via multi-core rather than pure uniprocessor speed, why use C++? I can use Haskell and get much easier and safer parallelism with many other advantages.

You would need to enumerate those advantages for me to answer. Why then wouldn't you use Haskell instead of C?


For the same reasons he listed above, eg you want to use an ffi etc. This is not a temporary issue with c++ as you imply, there are really hard issues about the c++ programming model, eg exceptions and classes, being really hard to interface with other languages that work differently.

The question is not why Haskell not C, sure if you can use Haskell why not, but for most use cases you cannot. But most languages can be used instead of c++, Haskell or Java or whatever, with many advantages.


>> OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++?

Why does a medical doctor have to learn a little bit of Latin? After all, you should be able to find all the books and material you need in your native language or at least English.

C is to computing what Latin is to medicine. There's just so much history and important code written in C, that it's an important skill to master. Or at least know a little about.

These days you can spend your entire career in the comfort of a high level language working on a virtual machine and make a fortune. However, if you don't know C (and the fundamentals of how computers work) you'll be standing on a foundation that you cannot understand like a living in a cargo cult.

If you're passionate about computing and software engineering, you'll have a natural interest in how things work under the hood. Learning C is almost mandatory if you want to see how deep the rabbit hole is. Knowing it will certainly help when exploring the intricacies of processors and operating systems.

Learning C++, on the other hand, I think is optional. I'm pretty seasoned with C++ but these days I prefer plain old C for low-level tasks. In theory, it may be possible to learn C++ without knowing C, but in practice it's not. If you try to write anything with C++, it will be inevitable that you'll have to interface with C code. std::string and std::map are very nice but there's a ton of tasks that require using a C API (maybe through a wrapper layer).

Embedded and other low-level tasks are often written in C because in order to run C++, you need runtime support for exceptions, static & global constructors, etc. Porting the C++ standard library is even more painful. C++ without exceptions has very little advantage over plain C.


> If you're passionate about computing and software engineering, you'll have a natural interest in how things work under the hood.

When I was 12, I learned 6502 assembly language. The computer I had did not have a C compiler, only BASIC or assembler (you could also enter hex into memory locations, which was hardcore). Learning assembly is actually a LOT easier than people make out. Assembly is basically mnemonics for the underlying machine code, plus named locations. Assembly has everything a language needs for Turing completeness. Assign, Add, Subtract, Compare, Branch. And THAT is how the computer works 'under the hood'. C is one level of abstraction above that, and while it's true that a LOT of software has been historically written in C, before C came along, most software was written in assembler or BASIC (which is older than C, for the historians).

> Learning C is almost mandatory if you want to see how deep the rabbit hole is.

Not really. I know what is going on 'down there', regardless of which language was used to compile the machine code. What is REALLY useful is to have really succinct, powerful, high-level abstractions to build software quickly and with as little code as possible.

> Knowing it will certainly help when exploring the intricacies of processors and operating systems.

If that's what you want to do, then fine. I'm too much of a utilitarian for that kind of exploration. I want to build stuff.

I think if you want to understand what's going on 'down there' in the 'rabbit hole', learn assembly language. There are only seven to ten basic instructions and you can learn them in a couple of days. You can build anything you want in assembly language, if you have an eternity to do it in.


> Assembly has everything a language needs for Turing completeness. Assign, Add, Subtract, Compare, Branch. And THAT is how the computer works 'under the hood'.

While what you say about Assembly is true, there's more to computer internals than doing arithmetic and control flow in the CPU. Virtual memory, DMA and IO are equally important, and the code that deals with that stuff is usually C code.

> > Learning C is almost mandatory if you want to see how deep the rabbit hole is. > Not really. I know what is going on 'down there', regardless of which language was used to compile the machine code. What is REALLY useful is to have really succinct, powerful, high-level abstractions to build software quickly and with as little code as possible.

You can book-learn what's going on under the hood but that's no replacement for getting your hands dirty. If you want to actually write code that uses memory and pointers (e.g. memory mapped files), runs in kernel mode or twiddles with page tables and virtual memory, C is the best language you can do it with.

> I think if you want to understand what's going on 'down there' in the 'rabbit hole', learn assembly language.

Learning Assembly language(s) is a very useful skill for everyone. But doing anything practical with Assembly is a futile effort, it's best to stick to C in low level stuff and resort to Assembly only when you absolutely have to. For example when you have to change between processor modes or write an interrupt handler routing, there must be some (inline) Assembly involved. But if you want to get stuff done and work with the interesting stuff, going all-assembly is not worth the effort.

I wrote a tiny multitasking operating system in Assembly. While it worked very well initially, as soon as the complexity went above one screenful of assembly, it started becoming very unwieldy. I moved on to C and got more stuff done. I could focus on the interesting stuff like scheduling algorithms and virtual memory when I didn't have the mental overhead of having to make register allocations manually or whipping up my own control structures.


Objective-C is a strict superset of C, so learning C helps a lot for any iOS or Mac programming.

C++ is also heavily based on C, so it helps to learn C++.

I agree C is hardly used anymore, and for good reason, but it's still interesting to learn.


> I agree C is hardly used anymore

Any time you want to provide libraries, you'll likely use C: all languages have C FFI, and it's not possible to have a C++ FFI. So you'd have to rely on `extern C`, and then you have to build a bunch of stuff over your OO code so it can be used procedurally.

Often not worth it, C is the lowest common denominator of languages, if you want to be accessible to all languages... you'll probably use C.


> Often not worth it, C is the lowest common denominator of languages, if you want to be accessible to all languages... you'll probably use C.

Personally I see that not so much as a feature of C, but as a limitation of other languages. Interoperability is a Hard Problem(tm) which deserves more thought and effort than it currently receives. It's easy to say 'If you want interoperability, use C' because that's the current state of affairs. It would be better if interop was a solved problem.


You need a common language to interoperate. Currently, C is that common language: everybody understands C.

Some languages have built specific language interop (e.g. Erlang with Java), it's usually broken and often not even as good as C.

> It would be better if interop was a solved problem.

It is: go through C.


The Linux kernel is in C. Large parts of the Gnome project are in C.


Also the GNU utilities, Apache and nginx, and the odd interpreter (Perl, Python, Ruby) or runtime system (Haskell), OpenSSL, qmail, Emacs' and vim's core, etc.

But yeah, apart from that stuff, C is hardly used.


> I agree C is hardly used anymore

Ehh what? From the top of my head I can think of these things written in C:

linux bsd windows nt kernel python php perl sqlite gcc glibc gtk+ apache nginx gimp blender mplayer wine x264 ffmpeg libjpeg curl/libcurl zlib rsync

And there's obviously tons more I could think of if I spend some more time, then we have basically the entire embedded industry.


If I wanted to do iOS/Cocoa programming, I would go straight to Objective-C, bypassing C without stopping, but that's me.

I learned C++ without ever learning C. Although, one could make the argument that in learning C++, I learned about 80% of C anyway. I can debug and fix C code, but I don't enjoy it, and avoid it if possible.

C is interesting, in the same way that Cuneiform is interesting. Personally I just find the Roman alphabet a lot more productive.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: