I first started programming C in high school. Most of what I learned was from a book I bought myself. The class itself wasn’t very good. The book I had on C didn’t teach me everything a beginning programmer needs to know.Knowledge of good coding style was something I lacked. Without any examples of good style in source code I developed an odd style that used really complex for statements. They made sense to me at one point but after I had written them they were both hard to debug and hard to read. I didn’t improve until I started learning programming again several years later.
My dad and the book Code Complete taught me practically everything I know about style and debugging. How Not to Program in C++ by Steve Qualline is a book with a theme similar to Code Complete. It has many examples of how not to program and programming practices that are just bad.
I enjoyed reading How Not to Program in C++ and think that it would have helped me when I was less experienced. The book is made up of many small examples which make it easy to read periodically. Reading it would be a good way to spend small bit of extra time. Most technical books are not suited for that.
Small programs featuring bugs is what the book contains. Most are one page long. Introductory text explains a little about the program. After that is line numbered source code featuring real live programming bugs. After the code are page numbers for hints and the solution. Many of the programs have a random joke or anecdote after the source code.
I thought the author’s sense of humor was very much like my own. The jokes were a combinations of random style humor and programmer humor. Some pages just had one sentence like “This page isn’t intentionally left blank.” While other pages had programmer humor like
“Shakespeare has given us the age-old question, “To be or not to be?” Computer science has given us the answer: “FF”.
“0x2B | ~0x2B == 0xFF”
One of the versions of hello world uses fork. That is humor.
Reading through one of programs in the book involves a few steps. First step is to read the introduction and title for a clue to the nature of the program and bug. The title is often a joke based on the bug. A program with the title “No Comment” likely has problem involving comments. The second step is reading the source code and looking for a problem. The problem might be silly mistake or it might be mistake in the logic. It’s often something silly which reminds me of my own code. The last step is to read hints and the solution. The solution often gives a recommendation of how to avoid the problem by using a different style of programming.
Many different bugs are covered. Most of them fall into the syntax error, misuse of a common function, and misuse of a language feature categories. I felt they were well chosen as they were mistakes I remember making. Usually I would be able to quickly guess the bug the source code would have based on what functions and language features the code used.
I only had a few problems with the content of book. Some of the bugs seemed trivial. Some of the solutions had to do with text output getting formatted wrong. I figured out how to format text pretty quickly when I first started programming. Sometimes I expected one of the chapters to have more complex bugs. The threaded bugs in chapter 11 were quite simple. The expert bugs in chapter 8 were more obscure then they were complex. I wanted bugs that were complex to the point that I would feel that I would never solve them without looking at the solution.
Besides the nice feeling I got quickly solving some of the simpler bugs I enjoyed the embedded programming bugs in chapter 11 the most. They featured problems that were not familiar to me since I’ve never done any embedded programming. They mostly dealt with keeping the compiler from optimizing out code that’s only purpose was kill time before accessing hardware.
The majority of the source code is cross platform and uses libraries and system calls found on most operating systems. There is a little use of POSIX libraries also. It is mostly C++ code with a little regular C.
I think this book would be the most useful for somebody that has just learned the basics of C and C++. It is still a fun book for any programmer who enjoys solving bugs but is more useful for someone less experienced. The problems are more examples of things not to do then hard problems that would challenge an experienced programmer. I don’t think this is bad thing. It just limits who will get the most enjoyment and knowledge out of the book.
About the Author:
Corey Holcomb-Hockin is a programming, open source, and game design enthusiast. When I’m not trying to get my writing published on OSNews I’m designing a RPG in Blades of Avernum or watching programs compile on FreeBSD. I live in Otis Orchards, Washington.
Steve Oualline is a decent author. I have his Practical C Programming, and have found it to be one of the better ones out there that I’ve seen. Interesting enough to read, not overly long (a big problem I’ve seen in a lot of programming books. I like a book like Lord of the Rings to be long, I don’t like a 50 page chapter on how to type printf.), and good at cutting through the cruft. Recommended read.
When I was a young programmer the books by Thomas Plum were very helpful. They are what got me past the hack mentality of just getting the program to work to trying to write the best code I could.
Some of these books are out of print now and they only covered C because C++ was not important yet but I think most C/C++ programmers would benefit from reading them
Lakos is a little dated.
There just isn’t much on the bookshelf about the best ways to set up directories, tests, handle versioning, and all of the non-language-introduction, here-is-what-the-professionals-are-using sort of material. In fact, newsgroups are about the only public dialogue I’ve seen along these lines. Anyone care to opine?
0x2B | ~0x2B == 0xFF
Nope it’s
0x2B | ~0x2B == -1
-1 is 0xFF for 2’s complement bytes.
They mostly dealt with keeping the compiler from optimizing out code thats only purpose was kill time before accessing hardware.
Okay, I’ll admit I don’t have the book, and I don’t do embedded programming, but — Isn’t this why OS’s have “WaitSignal()” or “WaitSemaphore” methods? My understanding is that you shouldn’t be writing code whose purpose is to “kill time before accessing hadware.”
Or is he talking about programming in an embedded environment where there’s no OS?
i think a constant is considered as an int so 0xff is 255
-1 should 0xffffffff (int as 32bit)
Try this:
#include <stdio.h>
int
main()
{
if ((0x2B | ~0x2B) == 0xFF) {
printf(“equal”);
return 0;
}
printf(“not equal”);
return 0;
}
it will print not equal
For a 32 bit system:
0x2B is 0x0000002B (00000000000000000000000000101011)
~0x2b is 0xFFFFFFD4 (11111111111111111111111111010100)
OR them 0xFFFFFFFF (11111111111111111111111111111111)
Which in two’s compliment is -1. Which is what you’re seeing when you write the code out in C (0x2B are being treated as an integer constant).
However, 0x2B is only a byte. Declare the two constants as two unsigned chars and you’ll get an answer equivalent to the joke (255 = 0xFF).
I would consider both answers to be correct. Obviously when you not something you end up with all the ones and zeros flipped. Simply oring them together has the effect of causing all the bits to simply be 1. That’s going to be as many F’s as your system can handle. You can consider that as either -1 or 0xF…FF. It makes no difference! This is a daft argument!
“You can consider that as either -1 or 0xF…FF”
Nope sir. -1 is 2^maxbits i.e. for bytes/shortint it’s 2^8=256 which is 0xff+1, while the maximum representable is 2^maxbits-1 which in this case is 255=0xff.
Funny thing to read you on this people
“-1 is 2^maxbits i.e. for bytes/shortint it’s 2^8=256 which is 0xff+1”
Nope to you, sir. In two’s complement, to get the inverse of a number, flip the bits and add one. so ~0xFF + 1 = 1, the inverse of whatever 0xFF is in two’s complement. That’s -1.
And, for myself at least, a short is two bytes.
Indeed, in embedded programming, it is often the case that there is no actual OS, and the programming space/processor performance is such that it is preferable to throw in single C/C++ statement waits as rarely needed, rather than go to the effort of creating complex threading primitives. This was a common thing done on the computers built using the 65XX series processors, as the CPU did not have any particular manner of waiting for something to happen, or just wasting time, other than doing a NOP, which isn’t supported in C/C++ directly. Then again, I’d like to see a C++ compiler for a 6502 (C compilers do exist for the 6502, as I’ve seen one in use back in the 80’s).
So, what makes no sense to do on a modern PC processor (or heavier duty system with a threaded OS) often makes perfect sense to do on a small embedded CPU system with no OS. Actually, to some degree, the same sort of tricks used in embedded systems is also used in device drivers for very small delays. If in doubt, read through driver source code for multiple operating systems
C/C++ does have some language support which will allow “Wasteful code” to cause delays burning CPU cycles: it involves the usage of the keyword “volatile” to tell the compiler to never optimize any access to the variable. This, of course, is not something you should expect to use in common user level programs: that’s what threading primitives are best used for instead.
Thanks 🙂
I’ve seen the NOP on a 6809 processor; I just didn’t realize that there were embedded systems working without OS’s.
If you take a look at the Linux kernel you’ll see that a few times the developers do a read of IO port 0x80 in the code without caring about the result. The reason that read is there is to provide a short delay between meaningful IO operations while they complete (Eg ISA). It really doesn’t make much sense to drop out of the driver code for these really short delays.
I imagine embedded devices use similar tricks.
Many programmers claim to know C++.
Few do.
C++ is the culmination of a mutli-decade project to create the most confusing weapon of mass destruction in the coders toolbox. With the STL finally the anthrax of programming languages is complete.
Are there even a thousand truly competent C++ programmers in the world? I mean coders who can implement complex features with minimal bugs in a large project.
C++ programmers are better served by heading in one of two directions their project really wants to go – C or Java.
LET IT DIE.
Yes, it’s called using test drivers for your classes.
My argument against java is that it lets sloppy programmers get away with crappier code.
For the most part java and c++ don’t differ to make much of a difference. Each language has its massive annoyances.
Programmers who write with hack mentality vs design mentality cause the biggest problems. In most cases the tool (or language) used doesn’t really have as much impact.
Once again the fallacy rears its ugly head – just label the victims of C++ as “hackers”.
Well more people have been trampled by C++ using UML, Booch etc and other garbage than the casual coder. Methodologies can’t protect you from the monstrosity of C++.
If you say Java lets people write crap code, fine, these people would be better off with C than C++. At least C does not lay out the rope in front of you and give you the impression that you are going to climb up it instead of twist from it.
C++ has all the danger of C but none of the comperhendibility.
C++ has all of the features of Java but none of the safety.
LET IT DIE.
C makes it easy to shoot yourself in the foot.
C++ makes it harder, but you blow your whole leg off.
Okay, so C# does some cousin-of-Ruby things and cuts the scale of things down, but C++ is really lovely stuff. It’s for sitting down at a program that writes programs, in one session, and favoring recursion and aware that it’s going to be messed with by compiler directives. It’s the safe part of make.
I just pulled MirBSD, which promises to have ‘dropped all that C++ sh**.’ From OpenBSD. Freaking amazing to me.
I’m looking forward to the movie with Gosling and Stroustrup where Bjarne says “Who dares!?” and all that, and they do an idea tennis thing that makes Gangs Of New York look like a clean fight.
> Then again, I’d like to see a C++ compiler for a 6502
I used the 68hc11 many years ago.
Now I’m using the h8300/h8s family with the gcc.gnu.org to write C++ programs.
I would never thought that I could do C++ with the 68hc11, yes by using the gcc.
Never used the 6502 but I think it’s really close, right ?, to the 68hc11 so as gcc did for the 68hc11 it could do for 6502…
Maybe with 68hc11 using a simple class with some new and delete will consume a lot for a system with little ram and rom, but that’s another issue.
every language occupies its domain within the problem space … parameterised by such items as control, safety, abstraction and so on.
java has its place as does smalltalk and lisp. as does prolog.
and C ha sits place, not too far from assembler and fortran.
but C++ seems to be a contradition – it give you abstractions with no safety. it gives you power but with clumbsy semantics and syntax. a lose-lose.
various british university computer science courses discourage its use – and refuse to teach it. the opinion of these people surely means something.
I actually find Bjarnes book very good. Yes, it isn’t my first choice to use as a reference but he really explains the traps in the language (both with respect to incomplete compilers and odd sides of the language) in a clear and consice way.
People often complain at Bjarnes articles being aimed at beginners and only containing trivial stuff, but seeing how people program in C++ that kind of texts are obviously needed.
People how claim Java to be superior obviously have only used C++ with notepad and gcc/gdb. A good IDE is my best investment and I’m never looking back. Visual Studio presents me with memleaks, lets me debug threads nicely and have nice autocompletion etc. And my processes are 1/10th in size compared to a Java version.
Any language where an entire Turing Complete sublanguage (templates/generics) is felt needed simply to get around one of it’s design features (strong typing) was quite clearly designed wrong. That is C++, Java, and C#.
Seems to me that Apple have ot right with Obj-C and Cocoa – perfect level of abstraction – plus the safety net of Cocoa
But I liked it, time well spent and a good read. Good laugh when I read the part about not learning everything he needed to be a programmer in school. On my very first corporate programming job the guy handed me a ragged mimeograph of this, it has served me well and still does to this day so I rendered it in XML and preserved it for those who follow:
http://www.fullsack.com/tao/index.xml
As far as languages and compiler wars go it is un-wise to blame the nail or the hammer when you smack your thumb.
“The C puzzle book” http://www.amazon.com/exec/obidos/tg/detail/-/0201604612/103-683476…
It’s fun for the whole family !
@BlahCrapMadeUpName – you, and others bagging on C++ for it’s pitfalls, should read “Accelerated C++” – not that I’m trying to be a commercial for Addison Wesley or the authors of the book 😉
This book teaches a top down approach to C++, and utilizes C++’s higher level abstractions (especially the STL), in the context of solving common programming problems. In fact, what’s taught in “Accelerated C++” will be all one needs for about 80% of programming problems out there. This book is an eye opener for anyone intimidated by or not liking C++. It was for me. It changed my opinion of C++ and made it one of my favorite programming tools. It also helped me in my job.
Remember, with great power comes great responsibility. C++ gives great power to the programmer, but in the process demands great responsibility of the programmer. In short, just use it wisely and cautiously, to avoid blowing your leg off, and the rewards will be tremendous. Keep it simple, with liberal and effective use of the STL and good GUI libraries, and the ease and power and benefits of C++ programming will become abundantly apparent.
Here is a link to a small representative sampling of highly successful C++ projects:
http://www.research.att.com/~bs/applications.html
As for C++ being an effective tool, the proof is in the pudding, and the above link demonstrates it clearly. None of those huge, highly visible projects would have been successful if C++ were a bad tool.
@BlahCrapMadeUpName – also, you say either go with straight C (presumably for lower level stuff), or Java (presumably for higher level stuff), and disregard C++ altogether.
I agree with you whole-heartedly on C. For OS kernels, device drivers, embedded programming, compilers, etc, straight C is an awesome tool (C++ can do those things pretty well, too).
Java for higher level, on the other hand, can be a very effective tool, but has it’s major pitfalls as well.
First, the two main Java success stories have been J2EE, for internal corporate dynamic apps that are server based, and J2ME, for cell-phone and small device programming.
On the J2EE side, with IBM’s WebSphere and BEA’s WebLogic, as well as Oracle and Suns App servers and the open source ones like JBoss, J2EE has been a big commercial success. But it also has problems in that there are few programmers that can program J2EE effectively. The J2EE API’s are huge and complex, with lot’s of “blow your leg off” pitfalls, and it takes someone a lot of experience and know-how to avoid them. Thus, according to one article I read on “Java Developers Journal”, J2EE apps only have a 70% success rate (which is comparitively bad). With this in mind, to say that C++ is much harder is just ignoring the facts.
On the J2ME side, Java has really proven a good tool. It is widely deployed with few problems. J2ME seems less of a beast than J2EE.
But Java’s big failure is the desktop. The problems are the performance/resource hit that is caused by the JVM, and especially the horrible libraries for GUI development (AWT and Swing). The end result using these libraries looks bad and performs bad. IBM started the SWT, which uses native libraries, solving the problem. But that defeats the purpose of Java’s “Write Once Run Anywere” promise. At that point, if you are going to go native with the GUI library, you might as well go native with the rest of the code, and avoid the performance/resource hit of the JVM.
Java is a great tool for certain things, but falls short on other things.
C++ is a great tool for many things (probably more than Java), but can be daunting to inexperienced or poorly taught programmers.
All programming languages have their place, and were designed to solve certain problems. It is wise to put as many of them in your toolbox as you can. Flame wars about programming languages, while they can be fun, are rather pointless.
As far as languages and compiler wars go it is un-wise to blame the nail or the hammer when you smack your thumb.
Very, very well put, Sphinx. This kind of says it all, and hits the nail on the head 😉
I’ve programmed full time, professionally, for 14 years. I’ve used everything from VB (eeeegh) to C++. If I had to only use one programming language, I would pick C++. Why? Because you can do anything you want to with it. You can get as low-level or as abstract as you want. It’s an old language, but it’s still the most flexible thing out there. I wouldn’t use it for everything, but if I had the chance to use only ONE language, C++ would be it.
Of course, with that kind of flexibility comes complexity and the potential to harm oneself. C++ has a lot of features that are appropriate in certain settings, and not in others. Sure, multiple inheritance, operator overloading, etc. can be a bad idea for some things. But, as in all things, when doing something seems like a bad idea, don’t do it! Suppose you have a box of tools, and one of the tools is a shotgun. Let’s suppose you need to drive a nail into a wall to hang a picture on. Do you use the shotgun for that? No.
I’ve had occasion to talk to numerous people about programming, and some of those people have nothing but bad things to say about languages like C++, Java, or anything else commonly used in large, complex applications. They say things like “I like Python. It’s just as powerful, and a lot better. Smalltalk is cool too, because everything is an object.” Interestingly, NOT ONE of these people is someone I would trust to hang a picture on a wall, because of the scenario mentioned above. Most of them don’t appear to have the sense to hang a picture without trying to use a shotgun to do it, just because it’s there. THAT is the problem with these people, not the languages they’re using.
Once again you are indulging the “stupid people are stupid” fallacy by blaming the coder.
Sure for you C++ is the way to go. Unfortunately you do not live alone in your work environment. In the real world we have to look at each other’s code, and often in these scenarios, using C++ is a surefire way to doom a project, and of course it is well documented that this has happened many times. The scenario is always the same – the pasty-white guru who has lived in his cave mastering C++ for a decade declares that all must follow his path, but not all are as skilled, and soon said guru realizes that the only way to make C++ work is for the guru to do all the work, which usually means he gets burned out and splits or the project flops.
Once again, I am not promoting Java. My original point stays the same – the bit twiddlers would be better off using C instead of C++. At least C is something you can comprehend, easy to debug, and is well implemented by compilers and has a deep labor pool.
If you want to mention the C++ success stories then you should also recognize the large number of failure cases. Once again the scenario is the same – the guru presumes too much about his colleagues and ends up getting majorly burned by some of the “creative” applications of certain C++ features he sees around him.
The language is too complex. It is just too easy to go off the deep end with C++. Bit twiddlers should use C, which will not only result in more readable code (even if it is longer), but the binaries will likely end up being much smaller.
By the way I like the approach of the Mozilla group. They use C++ but put a limit on the featureset. Without this I am sure Mozilla would have been another C++ victim. Too bad there is no way to formally declare a sane subset and impose limits via the toolchain.
If you want to mention the C++ success stories then you should also recognize the large number of failure cases. Once again the scenario is the same – the guru presumes too much about his colleagues and ends up getting majorly burned by some of the “creative” applications of certain C++ features he sees around him.
Do you have any specific examples of C++ failures?
I’m sure there are many – same as with all other languages.
But providing high profile examples, rather than stereotyping assumptions, would be helpful to this dialogue.
The scenario is always the same – the pasty-white guru who has lived in his cave mastering C++ for a decade declares that all must follow his path, but not all are as skilled, and soon said guru realizes that the only way to make C++ work is for the guru to do all the work, which usually means he gets burned out and splits or the project flops.
This is about as much of a broad, sweeping stereotype as you can get. I’ve known plenty of programmers who were competent and productive with C++, who were normal working people and enjoyed their jobs using C++, both academically and professionally.
My current company has two “guru” types using C++ 90% of the time, while myself and another techie use it maybe 20% of the time. We all recognize C++ as potentially harder and more complex than, say, VB, but we also see it as a very powerful tool that you can be very productive with (using good libraries, compilers, and IDEs). And we rarely run into the typical C++ pitfalls, and when we do, it is usually debugged fairly quickly. My company has a very successful software product that uses a lot of C++ code.
And guess what? Each one of us coders is happily married, and we have lives. Three of us have kids. We’re not a bunch of pasty white gurus who’ve spent 10 years in a cave mastering C++ (well one guy has used it for 8 years, the rest of us the last 2 or 3).
I also code as a hobby in the evenings (some of the time). My favorite tool is C++, using QT/KDE/KDevelop/QT Designer on my Mandrake Linux installation. I’m married and have a two year old daughter (and we as a family remain active socially), so my time and ability to concentrate on complex problems is extremely limited. Yet I manage to code up plenty of apps (small scale, mostly), that actually work and don’t require tons of debugging (even ones that use “difficult” C++ features like direct memory management, inheritance, templates, operator overloading, etc). If C++ was this horrible, complex boogey-man of a language you’re making it out to be, coding these apps under my home circumstances would be completely impossible.
But go ahead and hate C++, based on erroneous assumptions and negative stereotypes – it’s your loss.
But then again, you could open your mind and look into how to use C++ simply and effectively. There are plenty of excellent resources out there to help you do so.
Hey if you think you have mastered C++ (in two or three years? No offense but I stick to my statement that I feel the number of actual legit C++ gurus alive now is less than 1000), than good on you.
No one is disputing that succesful software can be written in C++. I have seen succesful software written in sh, another terrible crippled language.
Some of you guys really need a lesson in binary
0 0 1 0 1 1 0 0 == 2B (2=0010, B=1100)
1 1 0 1 0 0 1 1 == ~2B (bitwise NOT changes 0 to 1, and 1 to 0)
————— OR (bitwise OR “1 or 0 == 1” )
1 1 1 1 1 1 1 1 == FF (F=1111, …)
I think the point of the joke was to stress how to “Not Program in C++,” hence the “8 bit versus 32 bit” confusion.
Hey if you think you have mastered C++ (in two or three years? No offense but I stick to my statement that I feel the number of actual legit C++ gurus alive now is less than 1000), than good on you.
I never said that I’ve mastered C++. In fact, I’m far from master level. Perhaps competent journeyman level, but not “guru” status by any streach of the imagination. And honestly, my overall skills in programming are probably intermediate level, regardless of language. I’ve been programming for 6 years, and I can get the job done. Maybe in another 20 years of continual usage of C++ will I even think that I’ve reached master level.
I have indicated that I’ve become comfortable and productive with C++, that’s all. I’ve taken the time to study C++ and practice it whenever I can. I’ve learned a great deal from Herb Schildt’s “C++ The Complete Reference”, Koenig and Moo’s “Accelerated C++”, the famous K & R book (for pure C), Charles Petzold’s “Windows Programming with the Win32 API” (pure C), and finally and most importantly, Stroustrup’s amazing book “The C++ Programming Language”. And I’ve taken what I’ve learned and practiced with these volumns and been able to successfully apply them both professionally and as a hobby.
And if a mid level programmer like myself can get to like C++ and be productive with C++, it’s a pretty strong indication that C++ is not this overwhelming monster of a mess that a lot of people make it out to be. It might take an investment in time and effort to get to that point, but IMHO anything worthwhile in life is that way. And frankly, the journey is just as much fun as the destination.
I run a C++ team, thery all understand C++ well and we have a good productivity rate.
I guess I must have got real lucky!…or some people on this thread have no f**kin idea. One of the two.