Ask Slashdot: Best Programs To Learn From?
First time accepted submitter camServo writes "I took C++ classes in college and I have played around with some scripting languages. We learned the basics of how to make C++ work with small programs, but when I see large open source projects, I never know where to even start to try and figure out how their code works. I'm wondering if any of you have suggestions for some nice open source projects to look at to get an idea for how programming works in the real world, so I can start giving back to the FOSS community." Where would you start?
The more lines of code the more difficult to get started as a general rule. Just find a small library that provides support for something you have an interest in. Tinker with it.
Two of my imaginary friends reproduced once
Nothing more to it, the gradual expansion of your own project will teach you the techniques you need... or you'll drown.
Off you go
Oh yeah, Good ol' BSD kernel. The best one in town.
I have often wondered the same thing. People tell me, "read the code and submit patches!" It may sound like hand-holding to experienced developers, but many new coders could really use an introduction to becoming a part of a community around a project.
And then do the opposite.
Works every time.
I suggest diving into Node. It is written in a very competent way, it's fast, small, efficient, nicely documented, does the IO correctly so no messy blocking function calls and threads synchronization madness, and is pretty young so the code base is not too big for one person to understand. Thanks to npm it is also very easy to write modules that are small, clean and have minimum boilerplate code so it's not like writing Java. There is a lot of code to be written so you may find writing and publishing your own useful modules pretty soon. Good luck!
Karma: Positive (probably because of superiour intellect)
Wesnoth has some of the most beauutiful C++ out there (yes, there is such a thing as beautiful C++). If C++ is what you want to work with, I recommend you start looking at their stuff. Play the game first, of course, so you can start to get a feel for what sorts of things it does. Then you should be able to start guessing where things in the code may be. Step through the code with a debugger too, of course. I find that "ok, I'm gonna try to make the code do this", i.e. starting with a specific goal, setting breakpoints, and stepping through the code is the best way to get comfortable with an unfamiliar codebase, no matter its size.
For C++ I would suggest Qt.
For C I would suggest Minix3.
Sent as ripples into the electromagnetic field. No single photon has been harmed in the process.
If you want examples of 'real world' programming, take a bowl of spaghetti, add some additional ingredients that you wouldn't normally expect to see in spaghetti, and then fling the whole thing against a wall.
That's what the vast majority of modern day code looks like, especially if the organization that wrote the code tried to outsource the development effort 'to save money' at some point during the dev cycle.
Why do you want to do this? Are you just curious or trying to get something on your resume? This is an important question because a diversity of advice can be given without knowing the answer to this.
I'm not an expert and probably not qualified enough to answer this question, but in my experience, you can't just start looking at a large project on your own and expect to get anywhere. As an example, any undergrad level OS course will only dig you skin-deep into the Linux kernel. The way I imagine things to work is, someone with more experience in the project you want to work on will help you get started contributing and learning the code base. Alternatively if you use a product extensively and know exactly what you want to contribute and why, you go in with surgical precision and try not to screw it up.
Linky. It's easy to build, well structured, covers a wide range of discretely organised functionality, has simple demo apps, and you can immediately see the result of tinkering with it.
If you were blocking sigs, you wouldn't have to read this.
A good place to start might be simple programs for editing text from the GUI. Starting with something like Kjots, gedit, or Kwrite is a good way to see how to build a simple interface and read/write files. Pretty simple and a step up from Hello World!.
Flexible bare-metal recovery for Linux/UNIX
Besides looking at the code of others be sure to look at the code you wrote a year ago and haven't looked at since. You should learn something about good comments and documentation. You probably will have ideas on how to better implement things. There is some truth to the notion that programmers don't really like the code they wrote for a project until they have thrown it out and rewritten it from scratch for the third time.
Comment removed based on user account deletion
The best program to learn from is the one that you have some idea for improving, something you use and can make better. The first patch I made to open source software was for bash. At the time I was use HP-UX at work and Linux and HP-UX at home. The KSH under HP-UX would do "tab expansion" with Esc-Esc, and it was killing me going between Esc-Esc and Tab (neither worked on the other). I first tried making a macro for it, but found that I had to change the C code to make it work.
So, don't look for the prettiest code to just read -- get in the game and poke at something you use. :-)
A tip I always give:
1. Start writing something you want. (It'll keep you interested)
2. Google the SMALLER hard parts (String Parsing, data models, misc functions, etc)
3. Use that code. (No one is going to blame you for copypasta on your own project.)
Eventually you'll understand how the copied code works. After a few projects you end up writing your own version because you're better than "that guy you copied from".
I am looking for volunteers to help me out with my open source project. Search for it on sourceforge using my nickname. It is java and even has android port if you are interested in programming for that platform. The project field is kind of "unsexy" so I am having trouble finding volunteers to work on it, or maybe my code is so messy that it is scaring people off :)
I highly recommend working on simply porting an existing tool to a new environment. You will be providing a useful service and learn piecemeal about an implementation style and technique. The more you port the more implementation dos and don't you will learn.
I suggest the book: Build Your Own Flight Simulator in C++
I read a version of it over ten years ago, and it helped me keep a perspective on projects.
All the code is spoon fed to you.
Check it out at
http://www.amazon.com/Build-Your-Own-Flight-Sim/dp/1571690220
Well, if it were C and not C++, I'd suggest this project. There are so many concepts involved in database development, that it can give a run for its money to OS kernels, graphics libraries and probably most specialized math/astronomy/healthcare related software.
But it's C.
You can't handle the truth.
The program source code type which I've learned the most from has been those which are written in the ``Literate Programming'' style developed by Dr. Donald Knuth to write TeX ( http://www.literateprogramming.com/ ).
The only program I'm aware of written as a Literate Program in C++ and publicly available is the Ynot logic simulator:
http://www.brpreiss.com/books/opus3/
William
Sphinx of black quartz, judge my vow.
... at least back in the days i was amazed how deep you could bury the int main() {}.
i think that the best one would (regardless of the source code qualities) an open source application that does something you are really interested in, or just find a simple usability problem or a simple bug.
then post your bugreport up on their tracker/mailinglist and offer to help with a patch with a little bit of help.
even if you don't manage to implement it, you might come up with a test case or at least discussion which will help you and the project. during the implementation attempt and/or testcase bulding you will most likely grep through a lot of code, commit logs and comments and might be able to implement your next idea.
if you are not familiar with the project's tools, you will be "wasting" a lot of time learning those while building a testcase/implementation attempt. that time you'll save during your next idea.
remember to start with small ideas. of course selecting a project that is both alive and non-hostile might be a good starting point as well.
One more thing: don't actually look at the npm source because it is extremely complicated, just use it as a utility which is easy. For good examples of Node modules to learn from take a look at Connect, Express, Socket.IO, Cradle and many other modules that you may find interesting. Have fun!
Karma: Positive (probably because of superiour intellect)
I think it would help if you told us what kind of projects you would like to contribute or to learn more about. Are you into OS kernels, IDEs, Ray Tracing, sound editing, etc. Then people might be able to suggest a manageable open source project to your liking (one which you will be more likely to brave through the learning curve), and resources for that specific project.
After playing the game for some while I began to read the code and found it fun. It's not like the experience when you're reading the Lions' Commentary. Besides it's of moderate size -- a complete game showing how components add up to the whole, but you can also learn from small, fairly self-contained snippets controlling some aspect of the game mechanism or UI.
There are a lot of little things that have never been cleaned up or standardized. Picking up something could take you a couple of ways; Do you want the understand the of the dynamics of what goes on between people, standardization process ... There is more than just code, there needs to be a direction to what needs to be accomplished.
Take a small thing that might be still being worked on, not to say this is what you should but more as a example,:
http://standards.freedesktop.org/clipboards-spec/clipboards-latest.txt
http://pvanhoof.be/files/Problems%20of%20the%20X11%20clipboard.pdf
There are a lot of little "dangling ends" still out there that needs a bit of help; standards that need to be worked on and other things besides just code work.
CPython's source is easy to find and easy to read. The core dev community has gone to pains to keep it simple. It's also pretty well documented and has a great community in general. You can download the source at python.org or look at it online (http://hg.python.org/cpython/). You make a mercurial clone on your local box for hacking and use bitbucket to host it publicly.
I've found the CPython source to be a fount of knowledge. A great place to start is the devguide.
Um the "kernel" (by which I assume you mean Linux) is not written in C++.
It should be, but it isn't.
I mean, it's full of objects with derivation and virtual functions, and structs on which constructors and destructors have to be called for everything to remain in one peice. Seems odd not to use a language which is every bit as efficient, has a familiar syntax and yet does a large number of common tasks automatically and without errors.
Oh, and the other thing is that linux has the vtable inside the classes rather than a vptr, presumably because they syntactic overhead of a vptr is too high. C++ is by default significantly more memory efficient in this regard.
SJW n. One who posts facts.
I was in the same boat and ended up just looking around on sourceforge.net for a project that was interesting. Sort by your language, C++, and pick something in pre-alpha (code is usually smaller). From there, find the "int main" and start following the code, line by line; if you get lost, google it or e-mail the maintainers. Download a copy of the source and start tinkering, break it, and repeat.
1. Find a program that interests you.
2. Find something you want to change about it.
3. Hack away.
4. Find a different program that interests you.
5. Goto 2.
Trying to understand all of the code in a large project may be an impossible task, and it's frequently not necessary if you just want to make a simple change.
how programming works in the real world
There is no such thing. Each project will have its own structure and idiosyncrasies, and even after looking at 10 of them you will only understand those 10, not "the real world" in general.
It is often a bad idea to teach yourself how to program by looking at someone else's code.
Why?
1. You are not getting best practices. There are coding guidelines that should be followed but there are always exceptions, and not everyone knows all the rules and will break them needlessly. I am a profession coder with decades of experience... But I am still learning new and better ways to do things and I look back at my old code and I go what the heck was I thinking. And the answer was Oh yea, I needed to get it done and I didn't know about some feature at the time so I had to make this hack to get it to work. Looking at someones code you will get the good stuff mixed with the half drunk, or just a bad day.
2.It is overwhelming. It is more then just being tossed into the deep end, It is being tossed in the deep end with weights attached to your legs. Especially if you new to development and don't know where to start you can see. If you start in the middle you will spend huge amount of time looking at code that does something very minor but with no idea why.
3. You do not have a goal. You can't just look at a program and say I know how it works... You really need a goal to fix something, otherwise you are looking at stuff blindly.
4. Those sneaky 3rd party libraries. Unless you are doing some real low level coding there will probably be references to those 3rd party libraries that will not really let you know how things work.
5. Too much to handle. A computer is a great tool for processing a lot of commands that is often too complex for a human to understand. A programmer rarely ever thinks of how the entire program is programmed only his own little world, or his world at the time. And will often go back to see some code that they written and wonder who written that and when.
If you really want to learn, I would suggest that you start out with giving you a goal project to make.
And search for small examples about the current feature you want to implement. Integrate the examples and alter them see what is happening. Once you get good at making your own stuff, learning the tradeoffs and pitfalls then you can start looking at someone else code to expand off of it. Making new code is easy, modifying others is actually more difficult. That is why I am not a Huge supporter of Open Source Ideals, and more of supporter of Open Specification.
If something is so important that you feel the need to post it on the internet... It probably isn't that important.
http://www.aosabook.org/en/index.html (And no, I'm not affiliated - just a fan)
Since the 90s I have been a proponent of reuse, not only internally to an organization, but as interface libraries with a low bar to entry. I found this book to be seminal in identifying issues that show up in large programming efforts and general dependency decoupling for interfacing:
Large Scale C++ Software Design by Lakos
come on fhqwhgads
Take a look at Code Reading: The Open Source Perspective by Diomidis Spinellis. I've had a copy on my shelf for years. He covers C++ along with other common languages, and has examples from both very large and small programs.
Don't go looking for "best programs to learn from." You won't "get" it. Each program has its own focus, and unless you are very interested in the subject matter, you'll just gloss over the important parts. I've worked with tons of other libraries and I always find myself asking "Why the hell can't I just do X" or "Why they hell did they do it this way?" Invariably it was because the library was written with a mindset with a better understanding of the topic and contract than my own. When I say "contract" I mean what the library aims to provide.
If you do want to increase your changes of using C++/OOP right, I highly recommend writing C++ using Qt. That is the best best-of-breed library, with an incredible breadth and depth. It is a well thought out, complete API.
Python also has an art to it which is called "Pythonic". Some things are more or less "pythonic" which means driven by the philosophy of the language that reverberates from the operators and APIs.
So I would say rather than just reading someone else's program, write you own using Qt or Python, and let those shape you.
Also, use Model-View-Controller as much as possible. (It is not possible everywhere though)
The only other thing I can advise on a completely general principal is always separate your data out from implementation. From array dimensions (who dimensions arrays anymore rather than use a STL like class? Static dimensioning makes it easy to exploit your code.) to constants and up to variables, keep that separated, because constants do change. Not often, but they eventually do.
Slashdot's rate-of-post filter: Preventing you from posting too many great ideas at once.
No, it isn't. It's been maintained by a sequence of cliques via contributor-mentor relationships and is badly documented, with certain subsystems displaying a horrible lack of orthogonality.
Linux, on the other hand, is well worth studying - it's really been written for practical engineers by practical engineers, arranged and documented so that anyone sufficiently competent can contribute. Don't forget the O'Reilly books on understanding the kernel and writing device drivers.
what about Debian and Arch? http://www.debian.org/ports/hurd/ http://www.archhurd.org/
On sites like spoj.pl there are plenty of easy questions. It's a good way to learn the basics, like sorting, input and output, because the judge will test your program for all the possible newbie mistakes.
Unfortunately, there are very few judges that will force you to use certain libraries (STL, boost, etc) APIs or language features (e.g. inheritance).
Pick any project that's not *too* huge, and preferably not GUI, because that adds many more layers to try to understand. What I do, when I've started new jobs, was to look at the main{}, and see what it does, to try to get an overview. Then I'll look at whatever calls I need to understand for what I've been asked to work on. I'll continue working at the highest level, until I get to what needs fixing or enhancement: that way, I try to avoid breaking something else by seeing where the changes will correctly fit.
If you find spaghetti code - one function hundreds of lines long, if it's not moving 5,543,540 fields, go elsewhere. Or rewrite it modularly. Correct modular code does *one* thing well, not 5 things confusingly. That way lies maintenance hell (as I like to say in interviews, job security is *not* "never let them know what you're doing", it's if I get a phone call at 16:45 on a Friday, or 02:15 some day, I do *not* want to spend hours figuring out how clever I, or someone else, had been a year or two before; I want to solve the problem and get back to leaving or sleeping).
mark
I think you already do.
This is the difference between C and C++: in C, whatever the code of a function says it does, it does; in C++, whatever the code of a function says it does is subject to be changed by templates, operator redefinitions, etc. Because of this it is impossible to make small changes without reading and understanding the entire codebase first.
Basically, if you want to get involved in a large C++ project, you either have a tour guide or very good documentation or make the huge investment of learning the entire superstructure of the program before making any changes to any part of it. It's kinda interesting how C++ encourages this kind of greater dependency between different parts of a program than C.
Forget magic. Any technology distinguishable from divine power is insufficiently advanced.
An AC above suggested ALSA modules, but many other projects accept plugins (my first thought was the GIMP, but that uses python). Pick something that you're interested in and write something that solves a problem with that. If it's a discrete module or a plugin you'll have more chance of deploying it.
...take a look at the source code for Luminance-HDR. While it's buggy, I've been pleasantly surprised at how well-organized it is, and it should prove to be very hackable.
tasks(723) drafts(105) languages(484) examples(29106)
I suggest download the Minix source and using the git portal for the OpenBSD source: git://git.freebsd.your.org/openbsd You can learn a lot from looking at simple tools like ls, and then looking at system libraries as well. And yes, I know it's not C++.
"If you plant ice, you're gonna harvest wind."
I'm not a big PHP fan, but I had to dive into mediawiki and found it to be very well organized. It made me realize that PHP didn't have to be bad :)
I seem to be in the minority in this regard, but in my opinion looking at source code to try to become a better programmer is a waste of time. Looking at the source code of a large project is just a bigger waste of time. Writing code is 10% what you're doing and 90% why you're doing it. Looking at code will tell you what it's doing, but it won't tell you why it's done that way. Add on top of that the fact that every developer has his/her own style and conventions and you're just adding more wasted effort trying to get to the "why" of the code. There's simply better ways to learn how to code.
Save yourself the hassle and go here instead. This book contains a wealth of information about building and working on large codebases (all open source), written by the developers themselves. This will cut through the boring bookkeeping that is 90% of writing software and get to the heart of why they are written that way.
The Linux Kernel is mostly C, with a little ML on critical parts. I think some modules are written in C++ though, and if you want to do this I think the kernel is not a bad choice and recommenced starting with a simple text driver, you can find examples for this around the net. Start with a simple module written in C, learn how to build it correctly and fit it into the kernel, then adapt it to C++, then publish the source on some web site. Presto- you've just given back. Then tackle a real task, maybe a usb driver to some fob or doohickey. Move on from there to ... i dunno, contributing to some oss robotics thingy.
Python: 'And then suddenly you have a language which says "we're all stuck with whatever the whiniest coder wants".'
Obviously doing stuff on your own is a good way to learn, but 1) it is certainly not the only way to start 2) HE ALREADY SAID HE WANTED TO DO THE OTHER THING.
Learning by maintaining someone else's existing code is not stupid. It isn't. Really. It's not even stupid, even if the code you're maintaining is bad. You can learn good things from bad code. And you can learn good things from other people.
I suggest QMail. The code isn't that big, it's well written, and it's modular (lots of executables calling other executables). I wrote some authentication plugins for it about 10 years back and as I recall it wasn't too hard to figure out what was going on.
Something to help you get started could be to try to clean up the code, add comments, and try to create documentation. There is a nice utility for generating developer documents here: http://shfb.codeplex.com/
I'm going to get a little bit snarky here, but there's a point to it.
Why go to all this effort to learn a language like C++ these days, if you're not already employed someplace where you're clearly able to earn more income fixing/building something specific for your employer that requires that skill-set?
As one of my good friends just realized, he's been struggling to master Objective-C so he could learn to code a few apps for the iPhone and iPad -- but he's "going about it all wrong", ultimately. After all, his reason for wanting to create those apps is a financial one, so he's far ahead to simply outsource the coding to another country where labor is relatively cheap, and simply "project manage" its progress as it's developed for him.
"Why tend the farm when you can own the plantation?" was his wording, I believe.... In a way, it's a shame our country has come to this (United States in our case), but it's a reality of the global economy. As long as someone can create a user account on a website like odesk.com and place want-ads for iOS developers, graphic artists, etc. and actually FIND people willing to do this work for as little as $7-9/hr. -- it's not remotely cost-effective to try to code an app yourself instead. Will the resulting code be a bunch of "spaghetti" that's difficult to maintain or decipher? Oh, quite likely! But the end-user won't CARE as long as he/she can download the thing for as little as 99 cents a copy and it basically does what it says.
It's VERY possible to spend as little as $800 or so and receive a complete, working game or other iOS app in return. Then, it's equally possible to turn around and earn at least $100-300 per month, month after month, for NO additional work beyond doing a little promotion of the app's existence and answering emails about it. More importantly, if one rolls the profits back into paying for development of the next app, the process can be done in a "wash, rinse repeat" process, ensuring a multiplication of monthly income. Don't forget, with tools like push notifications, one can announce the new apps to owners of the existing, previously sold apps, which helps drive more sales....
Obviously, the original poster wasn't referring to developing for smartphones .... but rather, using a long-standing, popular language for writing apps or even operating systems themselves. But my point remains.... We're reaching a stage where it's just not financially smart to hire developers at the kind of salaries or hourly wages they'd expect to receive for the type of work they're doing (and amount of learning required to be ABLE to do it). Outsourcing is becoming the new norm, even if it results in poorer quality code (and I think it often does).
The document management software we purchased, where I work, for many thousands of dollars back around 2004-05 used to be developed in-house, here in the U.S. Guess what? The entire last major revision was coded as outsourced labor in India. They retain a "help desk" in the U.S. to answer their phones and give the appearance you're still dealing with a U.S. based company -- but all the trouble tickets eventually get turned into work orders for Indian developers to do either as a "hotfix" or more often, as a required change for the next service pack or version of the software they have scheduled to release.
The special treatment that C++ gives to constructors and destructors makes things harder, though. They don't return any value. If the constructor fails your only option is to throw an exception. But C++ exceptions make code execution slower. Another alternative is to check the object through a method after construction, which a lot of STL objects do, but that's kind of messy.
Don't get me wrong; I program in C++. But this is one of the dilemmas that I've faced and researched, and I still don't know what to do about it.
The Linux kernel is a piece of good crafted code in comparison with most desktop projects. This is mainly due to working community processes which Gnome or Freedesktop.org lack. Before someone marks this as flamebait. There is and was a lot of bad communication between parts of the Gnome community e.g. between Ubuntu and Gnome, between users of Gnome and the GnomeShell team etc. And arguments like: "It is open source take it or leave it" where send out, which is nonsense as software is not only designed by the programmers and designers, but also shaped by user needs. So the feedback of users is important. That's why Ubuntu became so popular in the beginning. Lately that changed a bit and therefore their loosing user base.
However, there are projects with a good community model such as the Linux kernel (even if Linus is sometimes a little harsh). The Apache projects seems to have a good process too and Apache HTTP is a smaller project so it might be a good starting point.
The best thing right not to help the desktop FOSS community would be real community building. There are some efforts with common conferences from Gnome and KDE, but there are still big issues for users to be heard by the developers. So help building community processes is even more important than coding.
Whatever you start off with, give it a run through doxygen first. Esp. with C++, this will save you a lot of time looking up definitions of objects and other stuff buried in various (and overridden) header files.
Read the well thought out and put together documentation bwhahaha
The problem is that many of the C++ features you're talking about really are features in the C++ runtime library and that more or less needs an operating system. Building a kernel with it is absolutely possible and there are examples of that but it's a lot of hazels involved.
the most important thing is to have techniques that allow you to find your way. the language doesn't actually matter, but it does definitely definitely help if the code is documented in some fashion. i tried, for example, to work on fontforge with my usual techniques, and the code was so incredibly dense and uncommented that it was absolutely impossible to understand. but, exceptions aside, here's a starting point for getting into large projects:
* use vi. do not use graphical editors. do not use emacs :e # to go _back_ to the file you were originally editing (after using ctrl-])
* get a damn big monitor (or 2 monitors). open xterms at 80x60, as many wide as you can get.
* use a multi-window desktop manager (i use fvwm2 and i run a 6x4 grid: that's 24 desktops.
* be prepared to open (and background) up to 200 simultaneous files, across multiple windows.
* make sure that you open the files from the *root* of the project.
* open the files "by name", explicitly, so that you can do "jobs | grep {filename}"
* run "ctags -R" - it is your friend. then use ctrl-] on a function you don't know, and read about it.
* remember to use
* be prepared to print out the ENTIRE codebase, and flip through it, off-line, very very quickly.
* be prepared to do page-down, page-down, very very quickly, through as many files as you can stand
the main thing to do is to get a vague map of the code into your subconscious, as quickly as possible. then you will go "i've seen that before..." and you stand a chance of being able to hunt for it and find it.
you *don't* have to memorise the entire codebase - you *don't* have to even understand all of it. but you *do* need to at least have the techniques which will allow you to jump to wherever it is that you want to go.
ultimately, though, you need a goal. what, exactly, is it that you want to achieve? if you have no goal, you are pissing in the wind.
i added NT Domains Security to freedce - that's a good, simple goal. FreeDCE is 250,000 lines of code, and very well laid-out. it was therefore quite straightforward to add 6,000 lines of code to do NTLMSSP. took a couple of weeks.
i added python bindings to webkit - that's a good simple goal (ok, it was horrendous, requiring over 12 different skillsets, including c, c++, python, perl, autoconf, gtk, python c modules, IDL files parsing - the list just went on and on). webkit is a massive project, and also very well laid-out and structured. the first version of the python bindings took about 8 weeks, and the 2nd (faster, better) version took only 2. the reason why the 2nd version took only 2 weeks is because i hunted down the mozilla xulrunner IDL file parser, hunted down python-gobject's code generator, adapted the xulrunner IDL file parser to understand the webkit IDL file-format (2 days), then spent the rest of the time hacking codegen.py to spew out the data types from webkit, and to create a standard python c module.
so you say "you don't know how to get familiar with a free software project", well, i am not - i wasn't familiar with webkit, but that didn't stop me. i wasn't familiar with xulrunner, but that didn't stop me. i wasn't familiar with python-gobject's codegen, but that didn't stop me. i just got on with it, and just trusted that the surrounding code would do its job, and trusted that the bit of code that i picked up could be adapted.
so in many ways, tackling a large codebase is more about overcoming your own fear and feelings of inadequacy. sometimes not even i can do that, and sometimes i can.
This was the path I followed to enlightenment after I took my undergrad software engineering course in C in the early 90s. I set out with a similar goal to find what real world systems looked like with proper decomposition, class structure, commenting, etc. At the time FreeBSD was getting a lot of interest, so I decided to dive into that code base a look. That made my head spin and seemed to violate all sorts of tenants we were being taught. Shortly thereafter, I accepted an internship at Microsoft and thought "Aha! Now these guys are doing great and must have a truly excellent software engineering culture. I can really see some good code now." I cracked open the code base for Excel and PowerPoint and got lost in that for a while. A lot of the Excel code was still based around Simonyi's design in C, and actually had a reasonable core structure given the limitations of C. But it was also a real world system and had an amazing amount of cruft built up around it that was difficult, at best, to understand. Mac PowerPoint at the time was a hodge podge of Pascal, 68000 assembly, C++. Some of the code was clearly written with some serious thought and design, but a large chunk of it wasn't. My favorite code review during the internship was a bit of assembly that processed a code resource loaded on the Mac to patch in a fix to the OS routines for FileDialogs in order to prevent a crash in our application.
Maybe you're doing too much in a constructor? You could offload anything that can fail into a method that can return a value.
But I do Java/C#, so I'd throw the exception and tell the customer to buy more hardware.
Godaddy is a scam and a ripoff.
Check out WiBit.net. It's not really an open source project; but it is a site that, for free, teaches programming including C++ (also C, Objective-C, soon Java and C#). We have a forum where users can help each other learn. It's not a big thing, but that's one way to give back to the community. Not just on WiBit, but helping others learn what you have learned is a great way to give back overall :-)
Also by getting into a learning site you can meet others who are like you: they know a bit, but want to be involved with something bigger. You can get your own effort moving and maybe create your own open source project. We have a guy in our forums working on an open source game with other users of the site. Check that out here.
I started using Audacity under Fedora 14 recently; it's a nice piece of work. However, when I tried using the 60 Hz filter on some digitized LPs, I was pretty disappointed in the result. Don't know if it was user error (e.g., me) or lack of documentation.
Where the heck do I start to create a better 60 Hz filter???
Circle the wagons and fire inward. Entropy increases without bounds.
You don't really want a return value in a constructor, do you? I mean, you can do it, but do you really want to? I take issue with your premise that exceptions make the code slower. Well written exceptions don't add that much to the overhead, and they are the Right Thing To Do with regard to OOP. Return codes are NOT OOP, a throwback to procedural programming. If you stick to OOP principals you don't need to have anything to do with them. Use exceptions and state objects.
Python: 'And then suddenly you have a language which says "we're all stuck with whatever the whiniest coder wants".'
NB: The message above might reflect my opinion right now, but not necessarily tomorrow or next year.
The special treatment that C++ gives to constructors and destructors makes things harder, though. They don't return any value. If the constructor fails your only option is to throw an exception. But C++ exceptions make code execution slower. Another alternative is to check the object through a method after construction, which a lot of STL objects do, but that's kind of messy.
Well, bear in mind that what was true 5 years ago is not necessarily true now.
The C and C++ non RAII ones are pretty similar in structure:
struct f;
if(!init(f, params))
return fail;
versus
class f(params);
if(f.fail())
return fail;
I'm not convinced the C++ one is messier than the C one.
now for the RAII one, there is an interesting thing about speed. The C version has the error logic mixed up in the control logic. Modern C++ compilers put the unwinding logic in other pages. The C++ one can be faster if errors are rare, but slower if errors are common.
Exception enabled code used to be slow, especially in GCC. These days it is much faster.
SJW n. One who posts facts.
There is no way to learn without failing. Start something small and let it grow as needed while trying to maintain quality.
Understanding a code base that is large and new to you is a challenge.
Especially if it is crappy architecture.
What I do is use Doxygen to map out the code base.
Once mapped, you can use your browser to get the basic layout and workings of the project in matter of minutes.
Google Doxygen, and install it (install graphviz/dot first).
Then play with it.
You will be glad you did.
Especially the dependency graphs are a life saver:
use them to identify and weed out header file dependencies, and you can orders of magnitude faster build times as well.
Bram
Bram Stolk http://stolk.org/tlctc/
Maybe you're doing too much in a constructor? You could offload anything that can fail into a method that can return a value.
That's kind of the point of a constructor. If it *has* to be called to make the object valid then putting in the constructor makes it impossible to forget.
But I do Java/C#, so I'd throw the exception and tell the customer to buy more hardware.
Not even that. Whole classes of bugs simlpy won't happen, leaving more time to optimize the rest of the code.
SJW n. One who posts facts.
Most of the more elderly progs/dev here will tell you if you prod them hard enough that "being dumb" is the road to enlightenment - if you think you know everything already, then you're not learning!
Big codebases, many hands = you need to learn human psychology just as much as coding, and the "art of diplomacy" (also knowledge of when to get out and say - "die in a fire losers" - just in your head). Ego's and little Hitler's who think they are code gods can burn many a decent project.
Andy
Aspirations of tackling a large coding project are usually less than imagined. Most successful projects start as the kernel of one programmer who strikes the landscape and envisions how things will work. Then they flesh it out to a degree and move on or otherwise becomes involved in managing the code base. At some point they leave or move on. So the majority of new or junior programmers end up interpreting that code base, usually with little or no documentation. In the best of all worlds they attempt to internalize or get inside the mind of the missing programmer.. and "figure things out" for themselves and extend it.. often making assumptions and mistakes the original programmer might laugh at or never intended.. but that is how the code lives on. Programming Libraries, APIs and application sdk's are all formalized examples of this.. sometimes with better documentation, or supplemental documentation and work even better as learning tools. In the distant past Language standards served the same purpose before formal libraries were common, and to a degree still do until new libraries for new languages are built up.
There are two fundamental reasons for wanting to work on "big" coding projects anyway, one is that your curious or have the need to extend or work with an existing product, application or code base.. that probably isn't well documented, or doesn't have "learners notes" or "examples" of how to get things done.
The other is the perception that it is career enhancing or will give one an edge over less experienced programmers.
For the first, the best way is to tackle intimidation with small projects and just going for it.. experience good or bad breeds confidence and eventually success.
For the second, a whole lot has to do with personality and experience and confidence, part of which can come from working with big projects and code.. but the personality is better worked on in a coffee shop and basically communicating with people in a sociable way.. even on the internet through email.
Open source projects are a great way to collaborate and work on all of the above in a safe non-litigious environment, and its high profile.. and you can find people willing to help.
Schools and colleges are a more traditional way, but cost a lot and there are some barriers to entry put in place by convention and societal expectations.
The interface between the real world and the digital hasn't changed since Woz and Steve Jobs invented the Apple computer or Bill Gates commercialized the free software disk in the back of a book. How can this tool, software, help me do things that I couldn't do before?
In the early days it was a lack of hardware that forced us to reach with our minds and know the capacity of the code better than the designers of the language.. more with less. That world is gone.
Today another economic, the embarrassment of hardware riches, tons of ram and lots of hard disk space.. but a limited human lifespan.. causes us to re-evaluate the old rule of "re-invent it yourself -- you'll learn something".. we just have the perception that to make something worthwhile.. it has to be totally and completely unique. Rather I think we should "get over it" and use Libraries or examples as if they were hardware building blocks and move on.. if you need a smaller code base then "that is the project" build from something that's already working.. and don't try to place magic crystal bricks in perfect celestial harmony.. before you get started.
There is an example of this happening before.. when we used to pontificate over RTL versus TTL which circuits should I use to build a Flip-Flop to build my microcomputer.. now we're moving into the age of when the Mobile computer replaces the Microcomputer and the Data cloud replaces the Database. What is a Mobile computer? It's not a PET Commodore anymore.. I don't even think I know.. its still being made.. but the effect on Apple and Microsoft are being felt.. safety seems to be in the cloud.. but maybe not.. what about distributed emergent data stores? Like bittorrent, dropbox, and programs that aren't programs but organize our lives like calendars? eh..
Take something you like and/or use. Or something like what you do if possible. Load it in a debugger, trace in to main or the language equivalent, and see where the calls go. You'll see quickly how the files are organized (if they are organized).
The more familiar you are with the app, the more sense the code will make.
Choose several - I've found every project has its own style, organization, or other peculiarities.
As someone said above, the real world is not all open source. Most of what I've seen in open source has nothing to do with what is done at large companies. The closest you might come is Red Hat, their distro-specific additions to Linux. But that's still open-source style.
When you feel comfortable, go to something that will blow your mind. The creative use of the preprocessor in MAME/MESS, and the ploymorphic implementation in C, makes this a wonder to behold. And not a great example unless your intent is to make an emulator.
http://mamedev.org/
The point is to learn more than one way of doing things, and find what you are comfortable with. Not how other people do it. Because there is no one way. If you want the one way, read a book instead.
There is a book on that subject called:
Code Reading: The Open Source Perspective: Open Source Perspective by Diomidis Spinellis
ISBN-10: 0201799405 | ISBN-13: 978-0201799408 | Publication Date: June 6, 2003
New things are always on the horizon
For C code, I recommend reading the source to Tcl/Tk. It's beautiful code, well-structured and portable.
For C, learn from the best, and that would be John Carmack. :)
http://doom.wikia.com/wiki/Doom_source_code_files
I finally found you. I hate you. Not personally, but this kind of thinking. A TCP class raises a disconnected exception, the stream class raises an interrupted exception, the object class raises an error exception, and the application says "There was an error." What kind, and how do I fix it?
OOP error handling and code reuse can be done well, but it generally is not. The basic idea of a "return code", giving some sort of information or context about the error, is very important. Even if it's just preserving the exception information to bubble up.
I've collected probably a hundred Microsoft-specific error messages that don't mean what they say they mean. They add helpful text to say what you might fix, but that's a red herring. There is an underlying error which is caught but not bubbled up, and it leaves the user with little or no idea what to do.
You have to have the idea, if not the implementation, of returning something to the user.
And, I take exception to your assertion that exceptions don't make the code slower. Each class wraps its code in try/catch and has to deal with fairly complicated Exception objects in many cases. Did the file open? fopen() returns null, and you can get more information if you want it. OOP says you have to make an exception object and run catch code, and go up the stack and to the exceptions there.
Code that experiences no exceptions will not be noticeably slower, but code that relies on exception processing to try alternate methods or re-try will be a lot slower. This from someone who looks at C++ code at the (dis)-assembler level.
Um the "kernel" (by which I assume you mean Linux) is not written in C++. It should be, but it isn't.
There are reasons the kernel doesn't have any c++ in it (link is about git, but same deal for the kernel).
The best formatted (C)API that I ever encountered was the X11 client-library. Yeah - so sue me. No really - one function per file,same name for the file as the function, clear indentation scheme, always a comment (on top), well documented structures, etc.
Religion is what happens when nature strikes and groupthink goes wrong.
I'd say take things that are popular, well-used. libpng or zlib for example, or any other library that is most likely in something you use. Even if real-world code doesn't work that way, it's something that a lot of people are exposed to, if only via the API.
Usually there is sample code which shows how to use the library. Many eyeballs on that sample, and you have a good shared consciousness. It's not always how things work as I said, but it is what's being used.
If your codebase does stuff like modifying operators you'll find out that way. If, on the other hand, it's is heavily template-based, my best advice is to either learn a lot about those particular templates (e.g. the Qt library) or stay away for now.
Code monkeys try to read their way straight through the codebase. In order to succeed that way takes a lot of time and raw talent (among other things superb concentration, a memory like a bear trap, and a good feeling for C++ syntax). You can waste a lot of time before discovering you don't really have the talent to do things the hard way.
Software engineers on the other hand use tools like Doxygen and first try to understand the overall structure of the code and then selectively zoom in on something they want to change or improve.
My suggestion is to train yourself first to use tools (perhaps on a codebase you already know) and then find yourself a smallish but new project you can apply those tools to.
If "the real world" means the corporate world, do this. Take an application you don't care about and don't know how to use, and assign yourself a bug to fix, and give yourself a deadline pulled from a RNG.
Code is developed this way:
Start developement
Shrink the team
Fire all but 1 guy who does all the maintenance
Bring in contractors
Add a few people
Shrink the team
Fire the 1 guy who knows everything
Scramble to find someone who knows the application
Bring in contractors
Select any step above at random
I'm not trying to be funny. End result is quirks, inconsistencies, inexplicable code blocks, bugs, performance issues, and all kinds of other bad things.
1) Return codes used in a appropriate way, please. Not saying they Are Not useful at all, but should be used sparingly. 2) I don't do Microsoft, so I'm not going to defend what they do. 3) I've found dealing with exceptions to be easier. WHAT classes do in a "complicated" way? That's like saying ALL cars implement the transmission in a "strange and mysterious" way. I've not found that to be the case. If you're stuck in a procedural mindset then you're probably going to find exceptions strange and mysterious. Too bad. 4) So, you've found me. Tag, you're it.
Python: 'And then suddenly you have a language which says "we're all stuck with whatever the whiniest coder wants".'
It depends on what your true goal is. Do you want to become wizardly, or merely competent?
Study the libraries used to implement the code in question to become competent in that application. Most of the confusion of thought regarding code has to do with specific libraries used. By encapsulating complexity in libraries, it streamlines the main code - but then requires you to dig into the libraries to understand what's going on. This 'state' is difficult to maintain in their head for most people.
If you want to become generally 'wizardly' at all code you come accross - start off learning Assembly code for the gear you're most likely to encounter (probably INTEL processors). After that, everything else is easy. Following craw-walk-run - move on to learning about compilers and interpreters that you use (C/C++ and CPython or bash are good choices to look at). Finally, after you get a good understanding of the lower level hoops that your programs make the CPU jump through, then start looking at the higher level code you're interested in.
I like to conceptualise the different meta levels of the program stack -- from the microcode that defines the CPU functionality -- all the way up to the high level languages as boxes within boxes -- each level standing on the shoulders of, and building on the strengths of the simpler lower level constructs. Another visualisation you could use are those russian nested dolls -- one within another and so on.... If you can understand what is going on at the different levels when any one high level command is executed, you can have a better handle on what your code -- or any code for that matter, is doing. Computers are actually very simple when you get down close to the hardware --- it's all the cruft we've layered on top that leads to complexity - much of which is really unnecessary, and the result of people trying to code fast, rather than efficiently. I'm not suggesting everyone code in Assembler -- but there has to be a balance, a 'middle way' that avoids layers of high level garbage that you have to sift through because someone decided they wanted to use their favorite (big/ugly) library/framework, rather than implementing it in a more streamlined fashion. This state is largely the result of people seeing every problem as a nail, and every tool as a (their favourite) hammer - without any deeper understanding.
I think 'computer science' courses today give short shrift to that key understanding. This, as you may be able to tell, is a pet peeve of mine.
Lodragan Draoidh
The more you explain it, the more I don't understand it. - Mark Twain
Hello world.
'nuff said.
Trying to turn a rather reasonable post into some kind of battle? You sound like you need help to me.
Python: 'And then suddenly you have a language which says "we're all stuck with whatever the whiniest coder wants".'
Those are quite bad and biased reasons. So it's basically C elitism. Let's all ignore that C has problems of its own.
There's nothing to stop you from throwing an exception and passing a code into it. I do this with exception objects I derive from std::, for things like FAILED(HRESULT) or glGetError() != GL_NO_ERROR.
Absolutely. That post was an eye-opener!
If you can start a project in a decent debugger, and once you start tracing the flow of the program, you would find a part of the code where you can begin your contribution, because thats where you will begin to see the turning wheels inside.
-- It is the mark of an educated mind to be able to entertain a thought without accepting it. -- Aristotle
To quote the C++0x draft I've got, 18.6.1.1/9: "T* p2 = new(nothrow) T; // returns 0 if it fails". In general, I'd rather use the basic form that can throw an exception, but in kernel programming you might well want to use nothrow.
"When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
I had assumed you would have read at least a few of the replies etc.
c++ gives enough abstraction and odd feature combinations to allow people to make functional but a complete pain in the ass to maintain code.
While it can be more verbose, c is comparatively very straight forward, how easy code is to understand and maintain matters.
A TCP class raises a disconnected exception, the stream class raises an interrupted exception, the object class raises an error exception, and the application says "There was an error." What kind, and how do I fix it?
That's because the stream class and object class both did the wrong thing with the exception they got.
What you want to do in an exception handler is fix what you can, and throw up the call chain what you can't. For instance, when the stream gets an indication that the TCP connection was disconnected, they could perhaps try to re-establish the connection, but if that doesn't work it should throw the DisconnectedException it got up to their caller until either something either fixes the problem or the application crashes. But what you don't want to do is take the DisconnectedException, replace it with a different sort of exception with less information about what broke, and and throw that.
In other words, if you hit a hammer against your thumb rather than against the nail, don't blame the hammer.
I am officially gone from
That's also true of course.
Warning: I'm taking a wild stab in the dark.
It's written in C... But, it seems relatively small and does one job very well. It's also scientific and I think it's got a good sized userbase.
Anyway, you could always port it to C++. (i.e. basically write from scratch an object-orientated version of gnuplot, perhaps using some of the libraries gnuplot has for the real gritty stuff.)
Or, you could program some kind of C++ based GUI for gnuplot. Think like matlab or excel, only kept simple, stupid.
PS: I don't reply to ACs.
Linus' new divelog program is a good small project to read through. It does something useful in a concise way with C and has good coding standards that make it very readable.
There are reasons the kernel doesn't have any c++ in it (link is about git, but same deal for the kernel).
Those reasons are so terrible. It amount to:
It's all FUD, BS and lies.
SJW n. One who posts facts.
Forget C++, it's becoming outdated and too complicated. More platforms are using Java and HTML5 now, it's the future of apps for PC's and Tablets.
-- By all means let's be open-minded, but not so open-minded that our brains drop out.
And if the code that *has* to be called to make the object valid fails, how do you prevent that object from being used when it fails? Can't use a return code as the programmer may simply ignore the return code and then blithely try to use the object that is now failing it's invariants. With the constructor throwing an exception, at least the code block that the variable was declared in will be exited, causing that variable to no longer be in scope, and thus cannot be accidentally used.
Look at the libstdc++ for GCC and some of the boost project code.
That code has production quality, is written in a style that actually utilizes c++. Beware that c++ recently got quite a few new features that have not gotten too much usage in libstdc++ and boot you may want to read up on that separately.
There is an *excellent* FAQ on most of the fine-grained aspects of c++ at http://www.parashift.com/c++-faq-lite/
In general, stay away from tutorials on the web, they are mostly written by people who have little or no experience and thinks they should teach the world about for loops or whatever because they just made one that doesn't crash themselves.
As a side note: that goes doubly for javascript, a much better search term to find quality code is ecmascript, unfortunatly there is no such good discriminating search-word for c++.
SLOGEN [ http://ungdomshus.nu : Sebastian cover music]
KDE is a big project, and has lots of apps where you can learn from. You can find small apps, big apps, libraries, WM, nearly everything in that project. It's well documented, easy to code thanks to Qt. You can start from the bottom with small tutorials, and move up in the chain when your experience improves.
I had assumed you would have read at least a few of the replies etc.
I did, and they're full of crap. You don't have to abstract away everything in C++ (what it is with that obsession with poor C++ programmers??), but it allows you to abstract away the irrelevent crap.
c++ gives enough abstraction and odd feature combinations to allow people to make functional but a complete pain in the ass to maintain code.
Bad code can be written in any language. It also gives you enough tools to make really clear, clean, maintainable code.
While it can be more verbose, c is comparatively very straight forward, how easy code is to understand and maintain matters.
No, not really. By that logic, assembler is easier to maintain and understand since each step is absoloutely blindingly obvious. The trouble is that if you only have tiny steps available, then you have to figure out the original programmer's intention.
SJW n. One who posts facts.
http://www.aosabook.org/en/index.html
You're weird.
SJW n. One who posts facts.
Exceptions actually add a lot of overhead (it used to be 20%+, I haven't benchmarked in a few years). And while they're useful in some circumstances, they can also lead to a lot of spaghetti code. They also require a very specific form of programming- everything needs to be a smart pointer, or you will leak. In addition, they aren't really all that readable- they're a glorified goto where the label can be multiple levels up. In general they should be avoided, and cases where they are used should be evaluated carefully.
I still have more fans than freaks. WTF is wrong with you people?
-1, Redundant
You say that as if it were a good thing.
You are welcome on my lawn.
It won't help you much with c++, other than in its commonality with C; but they are great programs to study. The code is clean; there is a minimum of comments, and there are lots of programs ranging from the trivial, like echo, cat; through interesting like ed, awk, to more ambitious bits like compilers, cpu emulators, debuggers, etc...
Gnu code is often very difficult to understand - huge variable names, #ifdef insanity, strange control flows. over-blown.
Spend a little time with clean C, and you'll want to forget all about the foggy, incoherent monster C++ has become.
Return codes are great until your function needs to return something useful instead. Now you have to allocate a pointer and pass it into your function and everything gets much less intuitive and elegant.
You make a fair point. Linux isn't a particularly theoretically interesting or elegant design. But at least studying it gives you a taste of practical, functional engineering. A lot of "why did you do it like that?" comes down to "because it works on all platforms and it's fast".
Studying one of the modern BSDs is a lesson in what happens when you devolve one code base into several competing platforms each of which wishes to maintain an air of exclusivity. Perhaps it's productive for an advanced coder to try to get to grips with one of them to see what happens when social engineering mets software engineering, but it's really not helpful for the beginner to do so.
Out of curiosity I looked at your link to Node. Then at the explanation about what the project is. It fits in half a line: "evented I/O for v8 javascript" and I have no idea what that means, even after 25 years of pro programming.
Actually it says:
evented I/O for v8 javascript - Read more
http://nodejs.org/
Surely clicking one of those links would be faster than asking for it on Slashdot and waiting for an answer? When you click the "Read more" link that is not even half an inch from what you've quoted you can find a big "Resources for Newcomers" section with links to the wiki and the home page.
JavaScript is of course the programming language. V8 is its high-performance implementation developed by Google for Chrome. I/O means input/output and evented means that it is asynchronous I/O based on event loops. I think that after 25 years of pro programming you should know that, and if you don't then you should at least know how to follow the hyperlinks to find it out.
Fairly typical of undocumented open-source projects, unfortunately.
Well if the only place where you look for documentation is the title of the project on GitHub then yes, it is fairly typical.
Karma: Positive (probably because of superiour intellect)
I've never understood this argument. Poor programmers can write unmaintainable code in any language, including C. If we judged the maintainability of each language on the worst examples we could find they would all be terrible.
There was some discussion of this on Reddit a while back.
I second Mike Pall's comments. The Lua codebase is relatively small, and your puny brain can probably understand all of it from top to bottom. Other systems, like GCC and GHC, would be much more challenging to understand completely.
You sound pretty arrogent to me...
I there are a few C++ modules, but a very few, due to the terrible and bizarre attitude of the kernel developers, who seem to want to insult users of C++, then purposfully make life more difficult, then finally spread the entire issue 3 feet deep in FUD.
Woa, that was a fun read :) *scratches zinged eyebrows*
Are you a grammar Nazi? I'm trying to improve my English; please correct my errors!
I'll second the recommendation to start small with a library or utility. Preferably a utility so it's easier to see how the pieces are supposed to fit together. With a library you frequently just get a group of classes without a good way to understand the underlying design.
I have to say that I think this is probably one of the best "Ask Slashdot" questions I've ever seen in my years here. It's directed to the right audience (the answers will actually be useful, as opposed to say, answers to a question about copyright law), it will have interest for a lot of of others who also want to learn and contribute, and it isn't a simple question that has only one good answer, so it will generate some useful discussion in addition to the usual /, noise.
We are the 198 proof..
Exception enabled code used to be slow, especially in GCC. These days it is much faster.
Yes, exception-enabled code is fast, until you actually have to process an exception. Merely enabling exceptions typically also doubles the footprint of code, without a single actual exception handler or exception thrown, simply because the compiler has to emit cleanups to unwind each and every stack frame, from each and every scope, in case an exception *is* thrown somewhere. Code to actually work with exceptions then add on top of this.
Given the outrageous expense of processing exceptions, anything that resembles normal or non-exceptional should never be handled as an exception. This includes things like TCP FIN (*all* connections end with it), EOF, poll timeouts, event processing (yes, I've seen it done!), not to mention regular C library and syscall error returns. I've seen people wrap things like mkdir() with an error check that throws an exception if it returns -1. Well, the program that used the wrapper of course used mkdir() all over the place just to make sure a directory existed (and to create it if didn't). So it got an exception in the TYPICAL case. Every call point was then wrapped in an exception handler that, well, did nothing! I consider that borderline incompetent. But I digress. On the other hand, the things that really ARE exceptional - heap corruption, out of memory, deadlock detection, out of file descriptors, thread creation failure, unmounted root fs, kernel resource errors, etc, etc - there's nothing to be done about. And any attempt to do anything at all will likely aggravate the problem. In the case of say a heap corruption, or stack overflow, it's unlikely that attempting to process an exception is going to do anything more than crash. And serve only to make it harder to debug because it crashed somewhere in a runtime routine that walks a table with links to procedures to unwind the stack, not the place where it was actually first discovered. You're IMO better off simply calling a panic routine that stops then and there rather than attempt to do anything else that would only aggravate the problem further (possibly leading to real data loss - "oh, a corrupt heap... lets try to save the document before bailing" or similar brilliance). Between the two, and given the footprint overhead and the inevitable abuse in the absence of adult supervision, it's best not to use them at all. The sliver of cases between the two where exceptions are useful is so narrow that it's no longer meaningful formalism.
Note that you typically don't get away from the error check of a return value. Instead you move it further down the tree, to the position where you conditionally throw the exception, instead of at the return of the function. The difference is there, but trivial.
By the way, I prefer your latter version for C++. Constructors really shouldn't do anything that can fail gracefully. A separate init() method encourages reuse of objects, making it easier to make them members by reference or value.
Oops, meant former, the f.init() version.
But C++ exceptions make code execution slower.
They do not. Exceptions improve performance by moving error handling code out of the main path of execution, increasing instruction cache effectiveness. They also eliminate all the instructions necessary to check function return codes, and defer error handling to the moment an error actually happens. Given a good implementation of the exception mechanism, they are nothing but win.
You can get into trouble when you start using try{}/catch{} blocks in complicated ways, particularly, nesting them inside each other. This is always a sign that you've designed your code wrong. try{}/catch{} should be used only to make decisions about what to do when an exception happens. All other sorts of stuff that needs to happens when an exception is thrown, such as deallocating containers and releasing resources and so on, should have been handled using proper RAII techniques without any try{}/catch{} at all. A well-designed program that uses exceptions may have literally hundreds of throw statements per try{}/catch{} construct, perhaps more. If you are writing try{}/catch{} all over the place, you don't know how to use C++ effectively.
The real downside to using exceptions, particularly in embedded environments, is code bloat. Most implementations use (rather large) object lifetime range tables to figure out which objects must be destructed, and in what order, when an exception is thrown.
Here's some more FUD, BS and lies from other people who, like Linus Torvalds, don't know what they are talking about and have zero credibility.
Fascism should more properly be called corporatism because it is the merger of state and corporate power. -- Mussolini
Where the heck do I start to create a better 60 Hz filter???
Digital Signal Processing: A Practical Guide for Engineers and Scientists would be a good place to start.
+1 Please mod up.
This is showing two very different ways to look at the problem. I agree with delegating to another component to handle a system wide error and raise the exception already!
Stop "optimizing", you've got bigger fish to fry.
.
Who did you buy that account from, whippersnapper?
You have a lower ID than the person you are replying to and yet you don't know that we used call "assembler" machine language.
By the way, assembler is the program you use for assembly. Try assembly language next time.
Oh, and your spelling of arrogant reminds me of rogue-likes for some reason.
No wonder you think C++ is something to develop Operating Systems in.
It is extremely well documented what every function in there is supposed to do, and most of the functions are actually written in C. Though I suggest you avoid printf. You'll learn things about C that you really can't learn any other way.
Some of the other standard unix utilities are also pretty good. I seem to recall that reading the source to awk and vi were very enlightening.
I'm trying to teach myself to set people on fire with my mind... Is it hot in here?
I learned on Fortran in the early 70's so that must be the right way considering how great I am now..............
Spaghetti code is pretty much gone because, except for rare grumbles about things like "multiple entry points" and that an assembler expert can still write more efficient code than a compiler, Structured Programming is clearly superior.
OOP, the next generation paradigm, has not displaced Structured Programming in any way close to the same extent. Why? Because it's not unequivocally better. Doesn't help that C++ is an especially poor realization of OOP. Name mangling? Templates? No automatic garbage collection? iostream? But those are only details. The major problem is with OOP, not C++. Class hierarchies can impose structure that is both unnecessary and detrimental. To avoid that, one doesn't use it. But then you have to ask yourself, why even use an OOP language? Polymorphism is cute, but it sure looks lame next to what Functional Programming can do.
Intellectual Property is a monopolistic, selfish, and defective concept. It is "tyranny over the mind of man"
code that relies on exception processing to try alternate methods or re-try will be a lot slower
If you're doing it this way, you're doing it wrong.
By definition, an Exception is something you don't expect to happen, even sometimes. You guard against it for the same reason that you check your return code in C even if you're certain the call will succeed: Because sometimes shit happens, and robust code demands that you fail gracefully when shit happens. Your catch code isn't for "oh, that didn't didn't work, let's try this", it's for "something happened, that, if I don't deal with it somehow, will crash my program." It's for "I'm bailing out because there's no reasonable way for me to continue." That programmers misuse Exceptions is an observation about programmers, not an indictment of the architectural reasons to use them.
Anyone who loves or hates any language, platform, or manufacturer, doesn't know what they're talking about.
Yes, because argument by soundbite works so well to establish policy. Just look at Washington!
Anyone who loves or hates any language, platform, or manufacturer, doesn't know what they're talking about.
There are many projects from which to learn. The way I would do the learning is to start with a small to medium sized project by a) get the user documentation
b) study the documentation and c) experiment/use the software.
After you understand the functional aspects of the product, your project should be to download the source, including makefile or build information. Then as a second stop, I would look in the source to find the explanation in the user manual, or vice-versa.
Looking at a source library collection without knowing the user functionality will be a most difficult learning process. I would say that this latter approach will lead to frustration and abandonment of your learning wishes.
Leslie Satenstein Montreal Quebec Canada
Because context-free grammar is a bad thing and having undecidable grammar is such a lovely feature where you can have no idea what a specific piece of code does (sarcasm).
Well, undecidable grammar (example)r is certainly a lovely feature c++ has that c does not (sarcasm)
Even horrible c code can be understood if you just sit there looking at it for a bit. That in c++ it is possible for that to not be the case is a horrible failing.
Please humor my pedantry, but perhaps this is a bad example. A TCP connection is a stream, so any other stream based on a TCP connection is not at the appropriate abstraction level to catch anything. If it's an HTTP connection (with an in-flight GET request that may have been lost), let that layer handle restarting the stream and re-issuing the request. If it's a lossey stream of video data, let that layer restart the stream, wait for the next keyframe to show up in the input, and resume sending new data. I regularly see people writing "adapter" layers such as a TCP iostream wrapper and trying to handle exceptions when it is wholly inappropriate to do so—they should simply guarantee some level of exception safety and then get out.
IMHO, what you really want to do is replace the exception handler with a RAII "guard" object that will perform cleanup in its destructor if .commit() has not been called. This gives you all of the benefits of a try/catch block without forcing the try/catch on your parents. Keep in mind that if an exception is thrown with no outer try block, the program may omit stack unwinding and abort with a nice healthy core dump. If a single "middleware" layer inserted a try/catch block with a re-throw, then your stack trace shows up in the middleware's (usually useless) function and the source of the std::out_of_range remains a mystery. (note: this is probably undefined behavior, but it is damn nice and worth leveraging.)
Go w/ Minix 3 - you'll learn what a microkernel is, learn to write device drivers for it, and at the end, could end up writing them for a whole bunch of h/w-s/w combinations. Just the mere #combinations should keep you busy for a while, not to mention giving you a company that could sell/license its drivers either to Linux/BSD/Hurd companies, or to the h/w manufacturers.
I read the questioner as asking which programming languages should he learn, in addition to C++. Did I misread him?
I've looked at this myself. It is very nice that in C++ the "default" way of approaching error handling with RAII plays nicely with the compiler's static branch prediction logic. However, it's not a sufficient argument for truly high-performance code. Either your compiler provides conventions on static branch prediction or it provides intrinsics such as __builtin_expect that give you control. Both of these will give you the same benefits as the C++ RAII style, and (in my experience) neither approach gums up the logic enough to hurt readability.
I mean, it's full of objects with derivation and virtual functions, and structs on which constructors and destructors have to be called for everything to remain in one peice. Seems odd not to use a language which is every bit as efficient, has a familiar syntax and yet does a large number of common tasks automatically and without errors.
Grasshopper, a good language is not defined by its features, it's defined by how well its features hang together.
C++ is a nuclear power plant driven swiss army knife. Perhaps worthy of a Sunday comic strip, but little else.
If "being uninitialized" is a well-defined state for the object, then I agree. For example, you can have an empty container, an empty string, or a disconnected TCP "connection" (fd==-1 is a natural state, and instead of init() you have connect() or bind()). OTOH, I frequently discourage my co-workers from reusing value-objects. It's just as easy to say homeAddress=StreetAddress(street,unit,city,state,zip) as it is to say homeAddress.init(street,unit,city,state,zip). I have seen the latter pattern contribute to bugs when somebody added a member variable and didn't think to add it to the init() method, whereas nobody seems to accidentally omit it from the constructor.
I'd find the source code to this Debian package and start by reading it:
http://ftp.us.debian.org/debian/pool/main/h/hello/hello_2.6-1_i386.deb
Must admit, I don't know how they got it all the way up version 2.6 ... what features did they add? And WHAT bugs did they fix?????
I am anarch of all I survey.
You can't learn from any project if you are not excited by it, no matter how small. Purely for learning this should be the approach:
1. Understand what you like. Look for similar project which is successful.
2. Download the oldest public version of the project and understand that.
3. Follow the subsequent versions and understand what changes were incorporated into them.
4. Join the newsgroup/irc relevant where this project's developers hangout and follow their posts.
There are two things you need to learn. One is syntax and approach to problem solving. This looks tough but will be easy once you get into it. Second is the group's dynamics and culture. Which might look easy from the outset but might prove to be tough once you get into it.
I think b4dc0d3r was using someone else's program or working on an OSS project, not writing his own (obviously he doesn't like how these exceptions worked, so I don't think he wrote them to do that). If he's speaking as a user, I can understand the thinking of the original programmer; an end-user isn't going to know what to do with a detailed error message, and I have often written exceptions to be both logged and then passed up to another, different error message for the user to see that has:
This is so the user can tell support what error they got, or the user can be asked to copy/paste or send it in an email, etc.
Not saying you're wrong, I'm saying that thinking about the UX for errors can be a good idea.
"We live as though the world were as it should be, to show it what it can be." - Joss Whedon via Angel
orthogonality.
oh, man! I can hear the apple lawsuit coming....
-- no sig today
The trouble is that if you only have tiny steps available, then you have to figure out the original programmer's intention.
And figuring out programmers intention is easier when the languages grammar is more ambiguous... not.
Context-free understanding of what code does is _useful_ something that c++ completely blows out of the water once you start abusing its more advanced features.
Can c be coded badly? of course, can you sit down and figure out what a code snipped is doing? yes. Can you do the same of ill coded c++, quite possibly no, this is a serious flaw.
I think he said about c++, not c.
First look a small C++ library, e.g. google "lightweight c++ library". e.g. http://vipbase.net/xmlparser/ Then compile it and run the sample. Enable debug messages or/and some debug messages. Play around and modify a few things.
Stop "optimizing", you've got bigger fish to fry.
I thought we were talking about a mature project (the kernel), where performance is critical, not a commercial product that started life six months behind schedule and twice over budget which has to play catch-up.
Ok, that sounded more negative than I intended, but if you're arguing that the current kernel development style needs radical change, then I disagree with you and urge you to study it in more detail. My argument is that the efficiency gained from embracing a well-understood (though perhaps flawed) pattern is greater and more predictable than the efficiency gained by radically changing pattern and upsetting the habits of so many highly skilled developers.
When the next generation microkernel is developed by a next generation of people using next generation tools and patterns and it manages push Linux aside you can shout "I told you so!".
Functional is new relative to OOP? The 1950s called, they said to rub Lisp in your face. Functional is also in no way, shape or form a superset of OOP. You can emulate OOP with functional code alone, but that's about how close the two are.
Find a project that has its main history all the way back to the beginning. Use a git or mercurial repo as then you will have the complete history on your computer. The check out the first commit and work your way through the history and watch how it gets built up.
As you move through the history pay attention to the commit messages and the changes that were made. You begin to really understand what the developer is doing. Eventually the project will get to be so big that you won't be able to keep track of everything.
I did this with the git source itself. It was pretty neat to see it come together. Then when I found a bug it was easy to find the part in the code where the bug actually was found.
Classes, inheritance, templates, virtual functions etc are all language features not runtime library features.
note: i'm known as plugwash most places but i screwd up registering that here somehow in the past and now can't register
Another alternative is to check the object through a method after construction, which a lot of STL objects do, but that's kind of messy.
Kind of messy but given that the whole point of constructors is that they are called automatically so the object is never in an undefined state you are going to have this fundamental problem.
a third alternative is to have the constructor create the object in an empty form (which can generally be done without memory allocation) and then fill it with data through regular functions.
note: i'm known as plugwash most places but i screwd up registering that here somehow in the past and now can't register
The main point is performance. Ryan Dahl wanted to write fast, scalable servers easily. We all know for years that threads don't scale but event loops do (see the second chart of memory consumption of apache vs nginx). Of course in order to have a highly concurrent evented server you can't use blocking system calls (which were a big mistake in my opinion to begin with - they are the only reason why you needed threads exposed at the application level for concurrency in the past). OK, so we want a portable, high performance, event-based, async-I/O, scalable, highly concurrent server. The obvious way to write such servers in a portable, OS-independent way was to write them in C using libraries like libev or libevent for event loops and libeio for non-blocking I/O. The result is great. But the problem is that it is not easy. C doesn't have lambdas, anonymous functions, closures or higher-order functions in a real sense, which all would make writing event handlers much easier. So Ryan was looking for a higher level language and found V8, the JavaScript virtual machine written by Google for Chrome. JavaScript has anonymous functions and closures. And V8 is fast. And also when you write JavaScript in the browser then you never use blocking function calls anyway, so people are already familiar with asynchronous I/O, events, callbacks, closures, futures and promises. Hell, you can even use Y combinators in JavaScript if you know your craft. Now, if only JavaScript had lazy evaluation and proper tail call optimization - maybe some day. Watch some talks by Ryan Dahl if you're interested and after 25 years in the field you should be. Oh, and Node doesn't have anything to do with the browser besides the V8 origins. It's all server-side. See the Wikipedia article on Node for more info and code examples. I'm glad that people who have been professionally programing for so many years are still willing to broaden their horizons. As I have written in the past it is not a universal property of programmers unfortunately. Have fun with new tools.
Karma: Positive (probably because of superiour intellect)
Even if it's just preserving the exception information to bubble up.
I do that. It preserves all exception/error information and can be used easily as long as the original source code is accessible. Although that is Java and not C++, this method has worked for me. As a mediocre programmer it is one of the areas of my code which I don't actually dislike.
Do what all enthusiastic new comers to FOSS do:
1. Find a project that interests you.
2. Gain an incomplete idea of how it works.
3. Re-write it from scratch and say how much better your solution will be when it is finished.
4. Profit
You may think me a tired, old, cynic. I'd have to disagree about the tired bit.
For os kernel: linux and join Linux kernel mailing list. For distro development: debian and its mailing list. For social network: diaspora.
Polymorphism is cute, but it sure looks lame next to what Functional Programming can do.
Mind of opinion. It just pisses me off that people keep saying these things as facts. Go back to your Functional Programming if that's what's good for you. Leave those who like OOP (even if done in plain C) to themselves. And the same goes for those OOP-bastards that pick on Functional programming "dudes".
Have you heard about SoylentNews?
I suggest Cppcheck: http://cppcheck.sourceforge.net/
- It is quite small
- It is a command line application (there is a small GUI also in case you would prefer working with that, but I would recommend the CLI first)
- It has very good unit test coverage (about 90% line coverage), so if you break something with your modifications, you will most likely notice it.
- The general idea is rather simple, source code is input, then it is preprocessed, then simplified, then passed to a number of different classes that try to find errors from the source. So following the execution path should not be very difficult.
- As it is a tool for static C and C++ code analysis, you will learn a lot about C and C++ language while working with it
- It is a tool, which you as a C++ developer most likely want to use yourself, so helping it improve will give help also you.
Your point would be valid, except I think the tactic is generally not to CARE about trying to enforce an NDA or copyright or anything else. You simply want the really cheap labor to code the thing for you. What they do with it after that is rather irrelevant. For starters, assuming your project requires graphics, you probably have 2 different people outsourced to work on it for one. One guy is designing the GUI screens or the game characters and look of the backgrounds for the game levels, or what-not, while the other guy is coding the core of it. Since only YOU have the whole "ball of wax", neither one of them is able to completely steal the app.
If they go off and redesign your idea into something similar but a little bit different, and start trying to sell it? That's ok. You've probably got your app out there first, which has inherent value. But additionally, you can add value if you keep up good communications skills with your customers and occasionally offer product updates (which you could again outsource to yet another new developer, ensuring the first guy trying to screw you by submitting your original app idea as his doesn't have access to the revised one).
Feh - I've not been around forever, but I've been around long enough to know none of the programmers I've ever met called assembler machine language.
Assembler is, at it's basis, homomorphic to machine language (although even that's not true any more), but unless you're actually twiddling 1's and 0's it's not machine code and that's a distinction every programmer I've ever met is thoroughly aware of - and indeed will hit you with a cluex4 for forgetting.
Pug
An Invisible Entity of Vast Power whose existence must be taken on faith alone: Liberal Media