Falling Into The Pit of Success

I’m with the commenters on Delphi. Go Delphi and you can be more productive than C++, without the performance hit and installed framework requirement of C#. (Yes, I know you can ngen your C# assemblies, but I can write inline assembler directly next to my Delphi code in the SAME program when I really want speed).

Not to mention that the VCL has been stable and enhanced for over 10 years, while Microsoft has retired VB6 and now Windows Forms in that time. So once WPF becomes old hat in 5 years, everyone can migrate all their code to the next greatest thing.

Go Python, Perl, Delphi, or anything else that doesn’t lock you in to a vendor that locks you out.

not to derail, but where was that picture taken?

How long do you have to code in C++ before you stop worrying about language and compilation and move on to actually thinking about the problem you’re trying to solve? How much of the C++ spec and Stroustrup’s book do you have to memorize before you stop getting nailed by “gotchas?”

you said:

“Think buffer overruns, memory leaks, double frees, mismatch between allocator and deallocator, using freed memory, umpteen dozen ways to trash the stack or heap”

are problems with c++? i think you meant ‘c’?

I program in c++/c all the time. Those problems dont exist in c++.

Tried c# a bit, yeah its easier to use and has a few improvements - do I want to use a language developed from just MS? - no way. Got burned by the hideousness of VB too badly, and C# looks too much like VB - yeah I know a lot of baggage what can I say.

Kriz,

For sure, dealing old pre-modern libraries in C++ is a major pain. The only time I’ve ever reinterpret cast a pointer to void* in C++ was to call Fortran libraries. Using Qt, an otherwise wonderful library, requires either a lot of custom wrapper classes or calls to new, which are potential memory leaks or worse in the absence of a C++ garbage collector (that’ll be in the next standard, FYI).

But there are standard techniques for dealing with old libraries and with libraries that have their own ways of doing things. Smart pointers, exceptions, and RAII are still best practice even when dealing with crufty libraries.

But all that strengthens my main point: language choice is all about the available libraries. Language differences are trivial in the face of available code reuse.

Old non-standard compliant libraries are a problem in any language that has been around long enough to have a wide assortment of libraries. Perl has the same issues. One day even Ruby will have problems in this regard. It’s something that you have to deal with.

I also agree with Tod McKenna. A poor programmer can write bad code in any language. A good programmer can write good code in (almost) any language.

“safe” code is entirely the author’s prerogative. Eg.

  • A program written in C++ overruns an array… and an exception is raised by the O/S which kills the program.
  • Same program written in C# overruns the same array… the CLR raises an exception which kills the program.

In both cases the programmer was responsible for the failure. In both cases the programmer had the same (better) choices available (prevent an overrun and/or catch the exception).

But what’s the difference to the user?

The user relies on the programmer who wrote the program… if that programmer fails; the user then relies on the programmer who wrote the next level (the host environment)… this chain continues until either a good programmer is encountered or the system itself crashes.

Personally, I love these new-age languages; my salary just keeps going up (currently more than double the average fulltime C# developer). Of course, I don’t usually write C#… C# doesn’t run on most platforms (and probably never will - some platforms I target don’t even have a C++ compiler and I have to write in original ANSI-C (not even // comments)). And most new programmers can’t write C++ (let alone ANSI-C). It’s fantastic.

the Big Dig isn’t something on which you want to model your successful API or project. It has massive (cost) overruns, (water) leaks, and (ceiling) crashes.

That’s exactly why I chose it, actually.

You need the intestinal fortitude to keep digging until you make it right.

If something funny is happening in the .NET libraries you can only hope that Google has something to say about it.

How so? You can decompile the .NET libraries, which are written in .NET, to see what’s going on under the hood. I read blog entries about this all the time.

The picture of a pit sure looks a lot like a girl blowing bubbles…
http://www.codinghorror.com/blog/archives/000834.html

“Consider your project a Big Dig”

It needs to be ill-thought out, horribly inconvenient to everyone in the area, and go tremendously over budget?

Surely there is a better project to compare your project to?

Typical e-penis waving comment that comes up whenever C++ is discussed. Are you saying any needlessly complicated technology is perfectly fine as long as a few people can use it efficiently? Perhaps the software you write is just as bad but it doesn’t bother you as long as a few of your users are comfortable with it?

The bottom line is either you produce good software or you don’t. You’re (i.e. the majority of programmers) much less likely to do so in a bug prone language like C++. Do you really think the bottom line for your customers is if their application was written in C++?

Time and time again, the C++ supporters are saying “C++ is a great language, but one needs to invest the time to learn it properly.” And they are basically correct. And that is precisely why C++ is not the best general purpose language choice today.

The Java, .Net, and several other languages don’t have the learning curve of C++. A junior developer can be more productive sooner. A team of junior guys with a smattering of highly experienced developers and a good architect or two can be very productive. The junior guys have opportunities to grow.

On a C++ project, the entire team needs to be senior. It is difficult to generate senior developers if you can’t employ junior developers. So you end up hiring junior guys and letting them make mistakes, because you just can’t get enough senior guys.

In short the path of the C++ developer is tackling difficult tasks, making mistakes and learning not repeat them. The path of the Java developer is performing well on simpler tasks, and progressing to more complex ones.

Frank Wilhoit: “C++ is only dangerous to people who have only half learned it.”

What makes it worth learning when the process of becoming an expert will take much longer than for any other programming language? Simply to pat yourself on the back that you can do things the most complicated way?

I haven’t met a perfect programmer yet and despite writing code for one kind of computer or another since the early 1980’s, I still have bugs crop up from time to time. Doesn’t matter if it is C#, C++, C, AppleScript, Perl… bugs happen. Good designs take care of some of the problem, good practices take care of some of it, automated testing can eliminate others, and code reviews can definitely flush out problems.

C# is different than C++ and each has its merits and pitfalls. Two years ago, I’d have picked C++ hands down for most any program. Now, C# is my go-to language, but I’m not married to it. It depends on the problem to solve and the domain.

I’m not all that wowed by JM’s “500-1000 lines of production code” comment. That really isn’t all that much code, frankly.

But, the ideas and expectations that JM wrote about - I generally agree with them. We should know what we are doing. For most/many of us, this is a career, not just a hobby. Folks pay good money for me to write code for them, so their expectations should be high. So my skill set should be high too. I’m going to make a bug or two - that is life, but I ought to be proficient and invested in my choice of work. Otherwise, I should be doing something else.

Interesting topic.

I have to agree wholeheartedly with JM. These days it is popular to bash C++, especially by those who do not have any practical experience in the language to speak of. Nevermind that the problems C++ is often accused of are easily and readily solved (using smart pointers when allocating on the heap, using std::string instead of char* arrays, using standard containers to manage memory, etc.). The fact of the matter is, C++ doesn’t mesh well with the average web developer mentality or make it easy for the toy programmer with little understanding of software engineering or computer science fundamentals to limp on by, and therefore it will continue to be the subject of such posts and articles.

A person complaining about C++ with little experience (or time spent learning the language) is like an American complaining about being unable to hold an intelligent conversation in Chinese after learning only a few basic phrases. One obviously can’t expect to be proficient, efficient, and effective without putting in the effort and time required. Those who don’t are usually contented to learn pig latin, and spend the remainder of their days communicating on a lower level, with a smaller vocabulary. Obviously Chinese would take more effort, dedication, and perseverance to fully learn and grasp, but it would open the door to wider and more effective communication. Likewise, C++ gives you the ability to solve MORE problems and gives you more choices on how to do so than other languages, allowing you the programmer to come up with the most elegant solution. Try modifying import address tables for Win32 processes in a language without pointers–it can’t be done!

C++ is not the right tool for every situation. For web development, I personally choose python. I don’t, however, take this as license to spend my time criticizing C++ for web development–I have better ways to spend my time.

For those who don’t need or want C++, fair enough. Please, however, stop ignorantly bashing it so that those of us who know better don’t have to listen to it.

I’m with Tod McKenna too. Nice point, Jeff, but what about entropy? There is no such thing as a Pit of Success. Success means hard work, means real thought. Actually, building such a pit, you say yourself, takes hard work. If the user of your API isn’t solving their problems on their own, one of the two is lacking, but not necessarily the API. Don’t dig deep and wide pits for people who can’t see in the dark.

Ironically, one can ask Andrew R the same question: what about entropy? A buffer overrun in C# will only raise an exception, while in C++ it might do no apparent damage for hours and hours, a vermin feeding on tiny mistakes, corrupting your data and building up your worst hangover.

JM put it very well ( JM on August 30, 2007 06:32 AM )regarding C++ for technical programmers, but possibly not for business programmers.

What he described is a technical language for professional technical programmers, as contrasted with business programmers. Technical programmers create technical software, e.g. OS’s, drivers, libraries, utilities, compilers, middleware, and maybe even sophisticated applications such as the components in an “office” bundle.

Business programmers create line-of-business domain-specific applications. Their main professional competency is knowledge of the business domain.

If one obligation of all programmers is to, “Do no harm,” then the expectation for these two groups and the languages they use are different.

It is fair to expect technical programmers to operate at the level of having read and absorbed the books JM described.

However, I think that business programmers can validly prefer languages that are easy to learn and easy to use. I have always valued the characteristic of some languages (and libraries) that let you start with a minimal amount of knowledge and use as much more as you learn. APL, Compiled Quick BASIC, spreadsheet tools and many others have this characteristic.

I also appreciate simple syntax. Compiled QuickBasic meets that characteristic. Yet it is almost as powerful as c, except for function pointers. VisualBasic added even more powerful capabilities over the years, reaching a peak with VB 6 but going downhill from there.

For business programming, it is reasonable for programmers to NOT attain full assimilation of the entire syntax and library. With a good IDE, they can exploit the help and online doc for anything they think should be doable, but never learned or don’t recall how.

Even for technical programmers, with so many categories of API’s within the operating system, application frameworks, communications, graphics, database etc. you cannot expect to know everything you will need on the next project. In a web services XML world, you cannot expect to know all the schemas and services, even those documented at http://www.oasis-open.org/

David Kra

It would be interesting to see if there has been any attempts at quantifying the resultant software quality of C# projects vs. C++ projects. Has the C# attempt to reduce ‘gotchas’ actually resulted in the production of less buggy products?

When I was thinking about MFC, I thought it’s really slow. But .NET is even slower. It’s depends on such a heavy framework.

Sometimes, speed is in the eye of the beholder.

http://www.codinghorror.com/blog/archives/000234.html
http://www.codinghorror.com/blog/archives/000299.html

I’ve recently had to switch from a computer game project involving a great deal of Python scripting to one that is primarily C++ programming. Since someone will ask, the cause of the switch wasn’t performance so much as maturity; we needed a battlefield-tested engine and didn’t really have time to write a full toolchain in the engine we’d been using.

As a game developer, I can speak towards the thought that “Everything is written in C++.” While it is very true that you’re going to find C++ somewhere in the code stack, mature game engines utilize a mixture of low-level and high-level languages to get the work done. A good craftsman has a variety of tools in the belt and is familiar enough with all of them to know which one to pick up for the task at hand. It is as foolish to write a tight-loop rendering algorithm where every ounce of performance must be completely managed by the developer as it is to write a complicated high-level game-state machine in a language that doesn’t even have a concept of a string primitive. Ideally, you arrange smooth boundaries between the sections of the program that are written in different languages and do the work with the tool that suits it best.

On the specific issue of C++: The biggest advantages C++ has as a tool are direct memory management, sufficient type safety to squash the most obvious types of mismatch errors, a ton of libraries written with the language in mind, and a relatively sparse feature set that makes it easier to build functionality on top without worrying about how the new functionality interacts with other aspects of the language. The disadvantages include a general sense that the ‘correct’ codepath is the one that takes more keywords (i.e. when would I ever want a destructor virtual? How often do I want to fall through a case statement? Why do I have to add code to two or three files to add one function?). The last advantage is also possibly the largest disadvantage; with so few low-level features defined in the language, many libraries aren’t compatible with each other (the STL should have standardized some of these features, but its implementation leaves much to be desired).

I think there is room for a language such as Q that draws the line in the sand between “language feature” and “library option” closer to the high-level languages; unfortunately, without the library support to offer actual functionality on par with C, new languages face an uphill battle. Allowing for backwards compatibility can make things worse; half the problems I have with C++ I’m convinced are design decisions made to ensure C compatibility. Conclusion? If you want to get work done, know C++… But feel free to use a more specialized language when the problem calls for it.

"For example, the GC. Yes, it does a good job most of the time, but when it doesn’t it REALLY doesn’t. And, there is no alternative. If you find that the GC isnt handling memory well enough for you, too bad. Rewriting your app in C++ is your only alternative, but by the time you find you have serious memory problems it’s too late for a rewrite. So you pepper the code with GC.Collect()s, it gets even slower, but it “works”.

I recommend you read this: http://msdn.microsoft.com/msdnmag/issues/1100/GCI/

Lots of C++ developers bash the .NET GC simply because they don’t understand it. In short - you should NEVER pepper your code with gc.collect() simply because you THINK your app is using too much memory. The CLR allocates lots of memory when it’s not needed by other apps to minimize the number of iterations of the GC algorithm - but releases it when memory is tight.