Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!

 



Forgot your password?
typodupeerror
×
Programming IT Technology

C++ Answers From Bjarne Stroustrup 386

Monday we had over 550 assorted questions and comments for and about Bjarne Stroustrup. Excellent moderation (Thanks, Monday Moderators!) helped cull this mass down to 10 extremely high-quality questions Bjarne has kindly answered in amazing depth, for which he deserves a loud round of applause. Update: 02/28 02:12 by R : Bjarne later took the time to dig through all the comments and reply to some of them. The additional material is appended to the end of the original Q&A session.

C++ Answers From Bjarne Stroustrup

1) Has OO run out of steam?
by rambone

After 20-some years, it's obvious that object-oriented programming is not a panacea. What are your thoughts on the future of the OO paradigm? What other paradigms do you see challenging it?

Bjarne:

Well. It was obvious to me 20-some years ago that OOP wasn't a panacea. That's the reason C++ supports several design and programming styles.

If you like long words, you can say C++ is a "multi-paradigm language," but simply saying "C++ is an OOPL" is inaccurate. I wrote a paper about that "Why C++ isn't just an Object-Oriented Programming Language" (download from my papers page). I presented that paper at OOPSLA - and survived.

In the first edition of "The C++ Programming Language," I didn't use the phrase "object-oriented programming" because I didn't want to feed the hype. One of the problems with OOP is exactly that unscrupulous people have hyped it as a panacea. Overselling something inevitably leads to disappointments.

That said, OOD/OOP is my favorite way of approaching design and programming. It just isn't the right style for every program and for every detail of a program. Some good abstractions are best represented outside class hierarchies. Trying to force everything into a hierarchy - especially into a single-rooted hierarchy - can give truly contorted programs.

I use a lot of simple data abstraction (classes without inheritance) and generic programming (templates and algorithms parameterized on types). However, I don't see these as "paradigms challenging OOP." Rather, they are complementary techniques. The key is always to find designs that fit the problems and use the language constructs that best represent the designs in the code.

Combinations of style can lead to very elegant code. For example,

void draw_all(list& lst)
{
for_each(lst.begin(),lst.end(),mem_fun(&Shape::draw));
}

Here, list and for_each() are examples of the C++ standard library's generic facilities. What they are used for is to invoke a virtual function of a base in a traditional class hierarchy.

You can even write a version of draw_all() that works for every standard container type with Shape* elements:

template
void draw_all(Container& c)
{
for_each(c.begin(),c.end(),mem_fun(&Shape::draw));
}

I chose this example to wake up people who still live in the dark ages and think that C++ is C with a few uninteresting additions.

Naturally, the code generated for draw_all() is as efficient as an list traversal code and the polomorphism used to call Shape::draw() boils down to a call of a function through an array of pointers to functions. The mechanism has been used to invoke device drivers.

New "paradigms" are touted every year, but most are not fundamental and few are genuinely new. Probably the most interesting are those based on "components" such as COM and CORBA. I'm undecided whether these constitutes a "new paradigm" or simply a new set of systems-level building blocks. Would we talk of Unix processes as a new paradigm? Anyway, my main concern with such components is that they are still less than perfectly integrated with programming languages, such as C++, and with the various "traditional" programming paradigms, such as OOP and generic programming.

2) C++ for systems programming
by ajs

C has long been the UNIX-world's systems programming language, and still remains that way. I know you don't like to compare languages, so I'll just ask if you feel that there are any core reasons why C++ either does not make a good systems programming language or failed to capture the interest of the systems C programmers.

Bjarne:

It is hard to teach old dogs new tricks.

Unix was first written 25+ years ago (I first tried in in 1973). All of its interfaces are defined in terms of C function calls, arrays, and structs. By the time C++ became available, there were 10+ years of tradition for almost exclusively using C.

There is no good reason for Unix programmers to avoid C++ and several good reasons to use it. However, there are no end of reasons/excuses offered. Let me list a few:

  • C++ is slow
  • C++ generates bloated code
  • There are no good C++ compilers
  • C++ is complicated
  • C++ doesn't offer much to systems programmers
  • "Advanced" C++ features are unsuitable for systems work
  • C++ code isn't portable
  • C++ doesn't have an ABI.
These are all either flat wrong or largely irrelevant. Some of these reasons make some sense on other systems (say on a minute embedded system without proper C++ tools), but not on Unix/Linux. Let me briefly try to explain why. Naturally, a complete discussion would take hundreds of pages because it is not possible to prove a negative. That is, it is not possible to prove that there isn't some problem that could be unsolvable for somebody.
  • C++ generates as good code as C for equivalent programs. Just try it.
  • C++ was designed to do that and current compilers deliver on that promise.
Naturally, you can write poor programs in any language. C++ is a powerful tool and in the wrong hands it can generate code that is *obviously* contorted and bloated. That may be preferable to the traditional spaghetti that poor programmers produce in C. Note that someone who is a good C programmer isn't automatically a good C++ programmer. Many problems have been caused by good C programmers assuming that they could adopt a semi-random collection of C++ language features and then magically become a good C++ programmer in a week.

A C programmer can benefit from C++ in a week, but only by sticking to a subset of C++'s facilities and by using libraries.

C++ supports powerful techniques that are at best weakly supported by C and learning these techniques takes time. C programmers might do well remembering how long it took them to become "master level" C programmers. I see no reason why it would take less time to become a "master level" C++ programmer.

The current generation of C++ compilers is far superior in standards conformance to compilers from a couple of years ago. The optimizers are shared with C. This can be a problem because it precludes some useful optimizations that cannot be done for C, but at least sharing of major compiler parts should convince sceptics that equivalent code it produced.

I'll deal with the roots of language complexity in my answer to question 9. Here, I'll just point out that many of the C++ facilities directly help people who needs to write efficient, reliable, and maintainable code. If you don't use these facilities, you typically end up simulating them with lower-level language constructs.

Even the "new"/"advanced" features of C++, such as templates, exceptions, and run-time type information (RTTI) are designed to meet the 0-overhead rule. If you need such features, it is more efficient (in run-time and memory space) to use them with a modern compiler than to fake their functionality in C. I do not know of a C++ language feature that has not been found useful and affordable by someone in some systems or embedded application.

Naturally, if you don't need a feature (often, RTTI is not needed) or if is unsuitable in a particular context (I can think of programs where exceptions would be unsuitable), you just don't use that feature. The 0-overhead rule is there to allow such decisions. This is not so different from not using a C feature that is unsuitable for a given application (in some embedded systems, malloc() is banned).

C++ is as portable as C. In both cases you need to encapsulate the system dependences to ease portability. Large classes of programs are portable across Unix platforms, and some programs can be made portable across other platforms also. The techniques are well known and when used well, C++ even has an edge when it comes to formalizing the notion of a system to allow trivial portability. For example, see the C++ library that defines the ACE platform (link on my C++ page).

The technical hardest problem is probably the lack of a C++ binary interface (ABI). There is no C ABI either, but on most (all?) Unix platforms there is a dominant compiler and other compilers have had to conform to its calling conventions and structure layout rules - or become unused. In C++ there are more things that can vary - such as the layout of the virtual function table - and no vendor has created a C++ ABI by fiat by eliminating all competitors that did not conform. In the same way as it used to be impossible to link code from two different PC C compilers together, it is generally impossible to link the code from two different Unix C++ compilers together (unless there are compatibility switches).

The current solution is usually a combination of using a single compiler and of providing C-level interfaces. This is not ideal - see also my answer to question 10.

That said, I think the main problem is educational. Many simply have seriously inaccurate ideas of what C++ is and what can be done with it. Often "inaccurate ideas" add up to a strong disincentive to learn. C++ is now very different from Release 1 from 1985. The ISO standard for C++ was ratified in 1998 and current compilers approximate it well enough for me to move programs that stress the newer facilities from compiler to compiler for performance testing on a variety of platforms. The standard library makes a difference here.

3) What would you do differently?
by spiralx

If you could go back to when you designed C++, what would you change and why?

Bjarne:

You can never go back. However, I think my most obvious mistake was not to introduce templates before multiple inheritance and not to ship a larger library with Release 1 of my C++ compiler. The two mistakes are somewhat related.

The reason I didn't ship a library was that I didn't know how to write one that was good enough. To get efficiency and type safety for containers, you need templates (and I didn't have an implementation supporting templates until 1988 or 1989). However, templates are not enough, you also need a design for containers and uses of containers that can deliver that safety. We didn't have such an architecture until Alex Stepanov came along with the STL. If you want a real firework of interesting opinions and insights, read this interview with Alex. The STL is the nucleus of the C++ standard library, providing the standard containers and algorithms, and the framework for their use and their extension with user-defined containers and algorithms. Naturally, this is extensively discussed in "The C++ Programming Language."

One problem with introducing MI before templates was that it encouraged further overuse of class hierarchies. Templates provide a simple and efficient alternative to some of the more contorted uses of inheritance.

Let me just mention something I wouldn't have done differently: compatibility. Had C not been there to be compatible with, I'd have chosen compatibility with some another language. Innovation should focus on improvements and what works should be left as unchanged as possible. That way, people keep their existing tools and techniques and can develop from a base that is functionally complete. Also it saves the effort to re-invent the wheel and to teach "new" stuff that is equivalent to old stuff. Thus, C++ is as close to C as possible - but no closer.

The flip side of this is that you have to deal with old mistakes and with compatibility problems. For example, I consider the C declarator syntax an experiment that failed. Nevertheless, I adopted it for C++. The alternatives and improvements I considered at the time would not have improved matters. I rate is as a minor problem. The more serious problem is to maintain closeness of language definitions as C evolves.

Also, there is no major language feature, I'd remove for Standard C++ - even in retrospect. New major facilities have to be added with care. Often, a library can provide functionality that people thought required language changes.

I think the C++ standards committee did a good job. It is not easy to create a consensus about a specification. Commercially competing companies have to agree and nations with conflicting traditions of standards work have to be satisfied. However, I think that the the time and effort was well spent. Standard C++ is a better approximation to my ideals than any previous version, and a great standard library to go with it. The time and effort is necessary unless you want to give free reign to "de facto standards" and proprietary languages. My 3rd edition describes ISO standard C++ and current C++ compilers approximate the standard.

4) Why no templated typedefs?
by Venomous Louse

Well, this is weird. Just the guy I wanted to talk to this morning!

It would occasionally be handy to have typedef templates (or template typedefs?! help!), something like this:

template
typedef bool (* func)( const T &r );

. . . but that doesn't seem to be legal. I don't recall seeing anything about this issue in The Design and Evolution of C++. So what's the deal?

Bjarne:

I, and the standards committee, underestimated the importance of templated typedefs. My guess is that they will be added in the future.

Actually, D&E (pg 357) does discuss templated typedefs and points out a technique that is often an alternative:

The extension is technically trivial, but I'm not sure how wise it would be to introduce yet another renaming feature.

Derivation also allows for partial specification of template arguments in the definition of a new type: template class X { /* ... */ };
template class XX : public X { };

I guess that in this case, my reluctance to add new features without a clear practical need caused problems. I'm more often accused of the opposite mistake - to be too aggressive in adding features - but as people learn to use what is available, new requests based on new experience are starting to appear.

Incidentally, your example "function of T returning a bool" is often best represented as a function object. And function objects are natural templates:

template
struct Predicate {
bool operator()(const T &r) { /* ... */ };
};

This way, you don't need a typedef; you can simply say:

Predicate* p;

Function objects also inline better than pointers to functions, so their use leads to faster code as well as cleaner code.

In general, I recommend "The Design and Evolution of C++" for people with "why is/isn't it like that in C++?" questions.

5) Question...
by MrHat

I (and maybe most of "us") know you solely through your creation of the C++ language and your assistance in authoring the ANSI standard for said language.

Aside from this one (albeit major) project, what do you work on from day to day? What projects are you currently involved in? Do you have any more language definitions/standards in the pipeline?

Bjarne:

C++ related work is a major part of my day. The standard is in "maintenance mode," but it still requires a bit of attention. I do some work related to libraries and programming techniques (I'll have a paper on "wrappers" in "The C++ Report" later this year), and I worry about the poor state of C++ education - and the way C++ is often seriously misused by misguided programmers. Look at me paper "Learning Standard C++ as a New Language" (download from my papers page). As you can see, I write a bit, give talks, and interviews.

In the standards committee, I'm spending most time on the performance working group. This group was created to investigate sources of inefficiency and implementation and programming techniques to deliver "lean and mean" code. Embedded systems is one area where this is needed. The current language allows close-to-optimal solutions, but not every implementation is well tuned for that degree of efficiency, and not every programmer knows the basic techniques for delivering compact and efficient code.

There is - as ever - much talk about extensions and new libraries on the net, but the C++ community still haven't learned to fully utilize the new facilities. My guess is that there is a lot of benefits to be had from better libraries. The Standard library in general and the STL in particular shows some of what could be done. Eventually, some of those new libraries will be standardized.

I'm trying to understand distributed computing better. To that end I read a lot and experiment with computerized gadgets. I worry about mobility, reliability, fault tolerance, and security. These areas of research were among the ones that led me to the design of C++, so in a sense I'm returning to my roots in "systems." Being a manager at AT&T Labs - Research also takes some time, but not as much as you might think, and it doesn't feel like real work: in that capacity, I don't produce code or technical literature.

6) Multiple inheritance
by MosesJones

Three linked questions:

a) Do you think that multiple inheritance is a requirement for a true OO Language?

b) When designing a system with multiple inheritance what do you see as the pitfalls to avoid, especially when it comes to maintainability?

c) Do you know of anyway to simplify the readability of multiple inheritance to enable first time users to do less damage?

Bjarne:

If you rely on static (compile time) typechecking, you need MI. If you don't have MI, many programs get contorted and you have to use explicit type conversion (casting) far too often. I wouldn't claim to know what - if anything - is "a true OO Language" but if you have to use explicit type inquiry essentially all the time, you don't have one.

I don't see MI as a particularly serious source of pitfalls. The obvious problem - which MI shares with single inheritance and every other powerful language feature - is overuse. I tend to use MI for simple aggregation and for adding implementations to interfaces. For example:

class network_file_error : public network_error,
public file_error {
// ...
};

and

class interface { // abstract class
// pure virtual functions
};
class base_implementation { // useful functionality
// data, functions, virtual functions
};

class my_implementation
: public interface,
protected base_implementation {
// data, functions
// override some base_implementation functions
// override all interface functions
};

In the latter case, you then have the users of my_implementation access it exclusively through pointers or references to interface. That was user code is independent on the implementation class and the system doesn't suffer from the so-called "brittle base class" problem. The implementation class can be exchanged for an improved version without recompilation of user code (except my_implementation itself).

Following those two styles avoids most problems. Naturally, you can find a more extensive discussion in "The C++ Programming Language (3rd Edition)" and in the new "The C++ Programming Language (Special Edition)." (See my home pages for details, sample chapters, reviews, etc.).

Actually, questions about multiple inheritance usually indicate that the questioner has been distracted into technicalities. To almost all programs, questions about use of abstract classes, templates, exceptions, and the standard library would bring far more benefits. MI is necessary in a statically typed language with inheritance, but it is not among the features that should be used most often.

If you focus on defining concrete classes to represent simple types and abstract classes to represent major interfaces, a good design is likely to emerge. Then, MI may or may not be needed to complete the program, but will be pretty obvious where it might be needed.

7) Questions
by Edward Kmett

Is there any hope for the introduction of constrained templates? Right now using templates is an exercise in willpower for the programmer. I know that constrained genericity went before the committee when templates were first introduced, but has there been any thought to revisiting that decision?

Another item that has gained a lot of momentum in the Eiffel community is Design by Contract, for which I would love to see a standardized approach in C++, but I doubt I'll ever see it.

Lastly, Bjarne, you were quoted once as saying 'When (not if) reference counting becomes available in C++ that it would be optional' (in a book on object oriented programming languages of which I cannot find on Amazon at the moment to post the ISBN). Has much progress been made on the front of making reference counted objects available? Or has your thinking changed since you were quoted?

Bjarne:

Actually, what I said was something like "When (not if) auotmatic garbage collection becomes part of C++, it will be optional".

Reference counting can be very useful for less frequently used resources, but I'm not advocating it as a general mechanism for keeping track of memory. C++ has good mechanisms for keeping memory management under control (such as constructors and destructors and the standard library containers), but if you need something more automatics, plugging in one of the available garbage collectors is the right answer (see section C.9.1 of "The C++ Programming language", my C++ page, or my FAQ).

Incidentally, the ISBN for the new hardbound "Special Edition" is 0-201-700735 and the ISBN for the softbound "3rd Edition" is 0-201-889544.

"Constraining" templates without taking away their power isn't as easy as it sounds. See D&E for a detailed discussion. One problem is that if you express template argument constraints in terms of base classes, you warp your system design towards a style where every property becomes a base class. This easily becomes a mess of over-used multiple inheritance and indirect expression of things that are better said directly. For example, It's clearer to say that a class must have a Specialization and partial specialization provide much of the expressive power that people want from constraints. For example, if I have a general sort template

template void mysort(Container& c);

and I want want special sort algorithms for vectors then I can simply write:

template void mysort(vector& v);

I'd like much better error messages from templates with type errors. Some of this can be done with better compiler technology (people are working on that) and some will be hard to do without some kind of template argument constraints/checking (but I don't know how to do that). Fortunately, a programmer can help. Consider the example I gave in my answer to question 1:

template
void draw_all(Container& c)
{
for_each(c.begin(),c.end(),mem_fun(&Shape::draw));
}

If there is a type error, it will be in the resolution of the fairly complicated for_each() call. For example, if the element type of the container is an int, then we get some kind of obscure error related to the for_each() call (because we can't invoke Shape::draw() for an int).

What I really wrote was:

template
void draw_all(Container& c)
{
Shape* p = c.front(); // accept only Shape*s

for_each(c.begin(),c.end(),mem_fun(&Shape::draw));
}

The initialization of the spurious variable "p" will trigger a comprehensible error message from most current compilers. Tricks like this are common in all languages and have to be developed for all novel constructs. In production code, I'd probably have written something like:

template
void draw_all(Container& c)
{
typedef typename Container::value_type T;
assert_equiv(); // accept only Shape*s
for_each(c.begin(),c.end(),mem_fun(&Shape::draw)); }

This makes it clear that I'm making an assertion. I leave the definition of assert_equiv() as an exercise to the reader :-)

This leads use to the second part of the question: design by contract. Since "design by contract" is a design style, you can apply it to C++. To do so you need to use asserts systematically. I personally prefer to rely on some specialized assert templates (see my 3rd edition). I agree that some such templates are good candidates for standardization as part of the library.

However, I don't think we'll see direct language support for things such as preconditions and postconditions. I don't think that pre- and postconditions written in essentially the same language as the program itself are a significant improvement on asserts(). Also, I'm not sure that the checking of class hierarchies afforded by language-supported conditions is worth the effort. For starters, people can gain very significant benefits today using current standard C++ simply by using assertions more systematically.

8) A quick question (ha!)
by jd

C++ is an Object-Based, rather than a "pure" (in a Software Engineering sense) Object-Oriented language. However, it's still centered around the notion of objects, rather than procedures.

However, all existing processors are procedural, and there is no real concept of an OO CPU.

Do you feel that OO languages, such as C++, will result in OO systems, at the hardware level, or will it always be easier to confine OO thinking to the abstract, using extremely complex compilers to translate between OO and procedural paradigms?

Bjarne:

One of the things I worked with before designing C++ was architectures for direct support of "higher level" facilities. I came to the conclusion that as long as hardware were growing cheaper and faster at a rapid pace, sowtware-based approaches would have an advantage over high-level hardware. These advantages are in cost, in flexibility, in the number of potential users, and in the vintage of computers that the software could run on (it takes longer to design and build a high-level machine than a traditional one).

In the forseeable future compilers mapping high-level constructs onto low-level hardware primitives will be the dominant approach.

9) C++ complexity vs. OOP simplicity
by hanwen

[Sorry for the potential inflammatory matter in this question].

How do you relate the complexity of current C++ with the much-touted simplicity of Object Oriented Programming?

Longer explanation:

Over the years, the C++ implementation has ballooned; If I recall correctly, your book the C++PL has more than doubled in size. C++ has become a very large and complicated language, and I doubt whether there are any individuals (besides you, that is) that know the entire definition by heart, let alone teams of programmers.

This means that it is not practical to use C++ fully in any project, and one also has to set strict guidelines for a project what features to use and which not. Seen, in this light, it is doubtful whether C++ has made writing software more manageable. So I think, that as tool for writing better software more efficiently, C++ is a failure.

C++'s evolution was motivated by a few mottos (you don't pay for what you don't use, C compatibility, etc.), and seen in this light, C++ is a success. Do you think that these mottos need reconsideration?

Bjarne:

Inflammatory? I think you are remarkably polite and technical here - and that your "editor/moderator" weeded out the real flames :-)

Complexity has to go somewhere and I think that putting it in the language in the form of direct support of common and powerful techniques is a good idea (or else I wouldn't have done it :-). Have you seen C code that simulates class hierarchies, parameterized types, or exceptions? Such code tend to be a complete mess of pointers, casts, and macros. In C++, such code can be clean and simple. Most importantly, the constructs have well-specified semantics rather than just comments explaining the intent of code fragments. What has happened is that the complexity has been transferred from the code to the language definition (and compiler).

You are right that there is little need to use all of C++ explicitly in every project. However, that doesn't mean that you need to impose restrictive "gudelines". When did you last use all of Unix or all of NT explicitly on a project? Would you like some manager to tell you exactly which OS facilities you could and couldn't use - independently of the nature of a project?

The typical "guideline" is straight out of the dark ages, based on information about the state of the world years ago and on strange assumptions on what is and isn't complicated. In the defense of people issuing such "guidelines," it must be said that the educational establishment has on average done a poor job at focussing students on the key programming techniques that are effective in C++. The results have been much muddled C-style code combined with bloated Smalltalk-style class hierarchies. The common denominator for these sub-optimal uses of C++ is losts of casts and lots of macros.

That said, I have seen many successful C++ projects (many more than failures) and much good C++. By good I mean, elegant, efficient, reliable, and maintainable. So, for many, C++ has delivered exactly what it was designed to deliver. Please remember that I made few, specific, and well-documented promises about C++ (See D&E and "The C++ Programming Language"). I was not a contributor to commercial OO hype.

I think I see a correlation between successful use of C++ and respect for its limitations (the deliberate constraints on its design) and a willingness to adapt design approaches to the facilities offered. For example, if you reject the use of abstract classes and build deep hierarchies with lots of data defined at each level, you really shouldn't be surprised by long compile times, frequent recompilations, and problems understanding what is defined where. Similarly, if you refrain from using C++ facilities and litter your code with C-style strings, arrays, plain structs, and lots of pointers into low-level data structures, you shouldn't really be surprised to get C-style problems rather than the promised benefits from C++.

The main tutorial presentation of the C++ language was 186 in the 1st edition, 282 pages in the 2nd, and 360 pages in the 3rd. Part of that increase is a greater emphasis on programming technique. The rest of the increase in book size (from 327 pages in the 1st edition to 1040 pages of the new special edition) is due to more information on programming and design technique, and the standard library. The "special edition" has 363 pages on the standard library - in addition to the uses of the standard library as examples in other parts of the book.

10) Questions for Bjarne
by scherrey

I was introduced to the C++ language in 1989 on the BIX online service by you and Greg Comeau whereupon the both of you set out to demonstrate (and finally convinced me) that this OO stuff wasn't just a fad and that C++ was a language that could efficiently implement it. This was during the time when Computer Language magazine had there "Language of the Month" feature article so languages had a tendency to come and go quickly back then.

As I recall, the two major goals that you stressed were a) to build a language that could get a handle on these huge projects that C was having difficulties with and b) to provide a balance of features and efficiency so that a developer should have to pay for features he doesn't use.

From my own experience using C++ in an extreme variety of projects (including very cramped embedded systems and large, multi-platform enterprise systems), there's no doubt that the great progress has been made on the first goal and that the second might have been fully achieved.

The biggest disappointment to me, however, has been the lack of ability to fully replace plain-old-C in system level development which is an area that stands to gain the most from the language's abstraction features and your stated goals of the language. I understand that early on, it would have been impossible to define standard ABI's since implementation techniques for things such as virtual method and inheritance resolution were very experimental. Now that a full decade has gone by and a surprisingly strong standard has been produced, these differences in implementations are more contrived than based on architectural considerations.

Presently the Open Source movement is growing wildly in popularity in commercial and non-commercial segments of the industry. Unfortunately, C++ cannot be used to provide linkable API's without either downgrading to severely limiting C-based linkage or forcing everyone to use the same compiler that wants to call your library because of non-standard representations of structures and calling conventions.

Do you think that standardized application binary interfaces should be a priority time now? If so, what should be the mechanism used to define these interfaces (defacto vs. formal standards, etc), who should do it, and what can be done to encourage this development?

Bjarne:

Hi Ben,

I think I nailed the efficiency, the generality, and to some extent the elegance. However, I underestimated the linker problems. I may also have underestimated the problems stemming from C compatibility.

If I were a platform provider, I would have made a C++ ABI a priority a couple of years ago, so that all vendors on my platform could be ready to provide conforming implementations when the compilers reached a high degree of standards compliance. I know such efforts have been started by Sun for SPARC and by a group of vendors for Intel's upcoming Merced architecture (IA-64, see http://reality.sgi.com/dehnert_engr/cxx/).

I would encourage everyone - and especially people who write software intented as part of a collaborative efforts - to encourage such platform ABI standards. If you are among people who can, lobby for a C++ ABI on your favorite platform. Unfortunately, I don't have specific suggestions on how to do this.

The compatibility with C at the system interface level has encouraged people to use C-style strings, arrays, and structs, where they would have been better off with some higher-level abstractions presented as classes or templates. Instead of leaving the low-level facilities at the system level and within the implementations of classes, people have let the low-level constructs - and pointers to them - permeate their designs. Type errors, wild pointers, array bounds errors, and memory leaks are the obvious results. Lots of macros and casts often adds to the obscurity of the code. It saddens me to see some of the unnecessary messes people get themselves into.

Poor educations is part of the problem and better education must be part of the solution. However, education can only do so much. Libraries and tools must that takes advantage of modern C++ must become ubiquitous before we can expect novice programmers to venture out of the C subset and apply more powerful techniques.

For starters, people ought to realize that starting to learn C++ is easier than starting to learn C. The optimal initial subset of C++ to learn is not "most of C" and C++ can provide a much smoother learning curve than is commonly done. See "Learning Standard C++ as a New Language" (download from my papers page) for a further discussion.

We have always had applications and specialized libraries that used C++ to give programmers a higher-level environment to work in. One significant aspect of the standard library is that it provides an example of that to everybody. Writing code using standard facilities such as string, vector, map, and algorithms really can change the way people program and the way people think about programming. I hope to see the techniques used for defining and implementing the standard library applied in many other areas to yield equivalent benefits in source code size, type safety, code clarity, and run-time efficiency.

I think the time has come to experiment with the more advanced/interesting parts of Standard C++. For example, my new Standard-Library Exception Handling appendix shows a style of programming that departs rather dramatically from "C common wisdom" yet leads to simpler code. This is not written for novices, though, but it gives a peek into the inner workings of the standard library.

Naturally, we must be more cautious in production code and there compatibility concerns with older code weighs stronger. However, we should not be so bound by older styles and compatibility that we never dare try out more modern and more effective styles. There now are native C++ styles, and we should use them.

-----------

I did take peek at the "raw questions" on slashdot.org. I had to resist the temptation to explain all of C++ here, and explain how to use it, and explain why the facilities are the way they are. For more information, have a look at The C++ Programming Language (Special Edition), The Design and Evolution of C++, and my papers.

It appears that I'll have to update my FAQ with several new questions, but that'll take me a few weeks.

Thanks for asking hard questions.

- Bjarne


Update: 02/28 02:14 by R : Additional comments...

Comment by Anonymous Coward
Friday February 25, @12:53PM EST (#44):

Some really, really interesting stuff. I'm going to forward this to everyone at work here.

My only negative question is did he have to plug his books so much?? It seems like he never passed up a chance to "refer to my 3rd edition of C++PL", etc..... I tend not to trust people who plug themselves and their products too much.

This, of course, is a minor concern. Thanks to /. for getting this great interview!

Bjarne:

Imagine a radio interview with a serious painter or sculptor. To such an artist, his/her work is what matters, but there is no way that work can be presented on the radio. You would expect many references to individual works and to museums where people can go to see such work. Descriptive words simply aren't enough. Poor artist can compensate by distracting the discussion away from their work and into their personal lives or politics, but that's not an option for serious ones.

I'm not an artist, but for an interview like this, I have a similar problem. I want to show code and serious discussions of problems, but the Q&A format doesn't allow that. My solution is to refer to my published work and to my homepages.

After all, my published work are the primary sources on C++. So, unabashed, if you want more see my home pages, read TC++PL, D&E, or my papers.

C++ and scientific computing
by J. Chrysostom on Saturday February 26, @12:32AM EST (#308)

As a soon-to-be graduate student in scientific computing, I sit and wonder sometimes why the support for mathematical and scientific computation in C++ is so limited. FORTRAN, the ugly and unmanageable beast that it is, is the only haven for computational mathematics.

Bjarne:

Have a look at the links to numeric libraries in C++ (such as Blitz++, POOMA, MTL, and ROOT). Maybe also track down some of the numeric C++ pages.

Comment by Davorama
Friday February 25, @12:37PM EST (#22)

These other questions were so great I didn't make the cut but maybe you folks have opinions you'd like to share?

What do you think of template meta programming? Do you consider it a boon, enabling clever programmers to do outrageously cool things like the Blitz project? Or is any benefit derived from it's use washed away by the obscure, nearly unreadable code it takes to implement it?

Bjarne:

I really like some of the things being done with C++ in numerics. The common thread is that templates are used to eliminate spurious temporaries. The results tend to beat Fortran in its own game while maintaining Math textbook notation. On my homepage you can find links to POOMA from LANL, Blitz++ from Warterloo U., and MTL from Notre dame. TC++PL has an explanation of the basic technique in the Numerics chapter.

I don't mind the obscure code in the implementations. Actually, I find most of that code far less obscure than, say, C kernel code. Where efficiency is paramount, you shouldn't complain too much about obscure optimizations, and anyway if you are a real user, you shouldn't read the implementation code.

Comment by sethg
Friday February 25, @01:12PM EST (#65):

A common theme in the answers seems to be "that complaint is based on outdated information; get a new compiler that follows the standard and use the STL."

For the benefit of us C++ newbies, does anyone maintain a chart showing which currently-available "C++" compilers violate which sections of the C++ standard?

Bjarne:

A first approximation: Compilers currently shipping from major suppliers are reasonably up to date (I use them). Examples include. Borland, GNU, Metrowerks, Microsoft, and SGI.

For more details see LANL's list (link from the POOMA site, see my C++ page) or a site in NZ that tries to keep track. Some vendors, such as Borland, keep the results of the Plumm Hall validation suiye public on their websites.

And, yes. It is my opinion that a very large proportion of problems reported with C++ can be traced to misunderstandings and misuse. A modern C++ implementation is a prerequisite for trying out some of the techniques that I'm suggesting, but please don't think that a new compiler by itself will help much. You need to actually change the way you work - and unfortunately there are many real-world factors that makes such changes hard (legacy code, lack of time to learn new techniques, co-workers, antique style rules, etc.). I dit not say it would be easy, just that it is possible and that many have succeeded.

Comment by hanwen
Friday February 25, @01:25PM EST (#77)

-- much stuff omitted --

Maybe nowadays some of my gripes may be soothed by the Standard Libraries, but I don't feel like learning yet another big C++ component, all the more because I know that afterwards C++ will still not be good enough (or will it ever have reflection, higher order functions, GC?)

In this light, I find your statement that "starting to learn C++ is easier than starting to learn C" dangerous, as are the examples in your "learning C++ as a new language paper" for they imply that any of these two languages can or should be a "first" language.

Do you really want people grow up with a language that has distinction between non-immediate objects on the heap and stack, no automatic garbage collection, pointers, no initialization, no higher-order anything?

You're educating people about C++: fighting misconception, telling them where it is good for. But you're not telling them what it is bad for. C++ is immensely popular, and people easily get the misconception that this popularity makes it a good language to start programming with, or to write their highly tweakable programs, etc.

Bjarne:

Actually, yes. I don't feel that it is right to start off people with a language that they don't have a chance using once they graduate. The Lisp and functional language community failed to make automatic garbage collection and higher-order everything mainstream even though they had the enthusiastic backing of the academic and educational establishment for more than two decades. Clearly, I don't feel that leaving people with a lower-level language like C is optimal either.

Given the current miserable state of programming and design education, C++ can be a major advance. Of course, people can also fail to take advantage of C++'s abstraction mechanisms and fall back to writing the equivalent of assembly code in C or C++. Through STL, the C++ community may have introduced more people to functional programming techniques and may have applied such techniques to more real-world problems than all previous languages put together. The fact that function objects are not the most flexible "closures" available doesn't detract from the fact that people understand them, like them, and use them.

The "Learning Standard C++ as a New Language" paper (link on my papers page) clearly states that I think that these approaches scale - and argues why. Looking at C++ as it was in 1988 (no templates, no exceptions, no RTTI, and no standard library) is really to look at a different language - one that simply doesn't support most modern C++ techniques.

If you want garbage collection, then there are excellent free or commercially supported garbage collectors available for C++ (see links from my C++ page). One reason that the C++ garbage collectors are so effcient is exactly that C++ has the distinction between stack-allocated objects and free-store-allocated objects.

Comment by Anonymous Coward
Friday February 25, @02:54PM EST (#118)

Yeah this is the guy who at one time usurped the name "C" for his new language, and was referring to K&R as "old C" around AT&T ... until Dennis Ritchie told him to knock it off :)

I think he does acknowledge that the committees have straightened out a lot of the problems in the earlier versions of the language, and I don't think he would claim current C++ is perfect.

Given his success and recognition, I'd probably be a bit arrogant myself :)

Bjarne:

I don't actually think that I'm seriously "humility deficient".

Remember, I worked with Dennis (though not closely) and closely with Brian Kernighan for more than a decade. I don't think I "appropriated" the name "C", but if I had, nobody would have had a better claim to it :-)

It was not me who referrend to C as "Old C." It was me who acted to defuse the confusion and the possible slur on Dennis by finding a name for "C with Classes" that was less likely to cause confusion: C++.

Also, I worked hard in the committee (few language designers have bothered with such "tedious details"), and I think the committee did a very good job.

This discussion has been archived. No new comments can be posted.

C++ Answers From Bjarne Stroustrup

Comments Filter:
  • by Anonymous Coward
    I think the whole point of C++ is to provide extensibility of the project without breaking 'client code' (code which calls derived classes via a pointer to the base class). This is accomplished via inheritance and polymorphism. The client code is relatively stable while the class hiearchy can change over time, hence extensibility.

    If the design of the project takes into account 'correct inheritance' and polymorphism, I think the amount of client code written will be relatively small. When I speak about client code, I am talking about the code which defines the application's behavior at a higher abstract level. The class hiearchy defines the concrete functionality, which can be modified, revoked, or extending by deriving a new class and overriding the functionality in the derived class.

    If you don't think your project will evolve and you don't plan to reuse your code, then by all means don't use C++. C will get your project done in record time. But you'll be in your private hell , rewriting functions and bending over backwards rewriting your main() and other functions which contain 'higher functionality'.

    Success with C++, I think, relies on how abstract your thinking is as well as how good you are with your C++ technique (polymorphism, templates, const correctness, encapsulation, design patterns, using the canonical class design). When you are good with your technique, writing the code just becomes mechanical, all of the malleable functionality is contained in the class hiearchy. The trick is using your C++ technique defining your class hiearchy to be flexible enough to change and still maintain 'object' semantics.

    I looked at your source archive, looks like you use public member variables in your classes, as a result you have broken encapsulation. How do you extend your classes without breaking your client code? Rewriting your client code from scratch?

    *wink* I think you're living in your own private C++ hell.

    I'd suggest you study Design Patterns and read the C++ FAQs as well as the TC++PL and if you really plan to create large C++ programs you'll need to read "Large Scale C++ Programming" by Lakos. Lakos will talk about strange and wonderful things like writing code which compiles and links faster. This way large scale code that takes 1 hour to compile and link can be done in 40 minutes. Interestingly enough, Lakos throws alot of Bjarne's OOD out the window, but you definitely won't have to worry about that until you have enough discipline to make your class member variables private.

  • by Anonymous Coward

    If not, don't even worry about it. Templates aren't going to be meaningful until you're reasonably comfortable with the rest of the language. For getting "reasonably comfortable" with the more commonly used features, I'd recommend C++: The Core Language from O'Reilly (the authors are Sapir and somebody else, IIRC). Templates are not covered in that book, but when you've mastered what is in that book, you should be able go to Stroustrup and deal with templates.

    C++ is very large and complicated and you can't learn the whole thing at once. Stroustrup's TC++PL is an absolutely rotten tutorial, because it was never meant to be a tutorial. It's a reference for experienced programmers. It's not "Son of K&R". Stroustrup isn't Kernighan, sorry. It's often damned hard to decipher what he's getting at, and his discussion of templates in TC++PL is totally unsuited for beginners.

    Here's the most simple and trivial template example I can think of:


    template<class T>
    class foo {
    public:
    T data;
    };

    foo<int> bar;
    bar.data = 8;


    foo<int> bar creates an instance of a class based on foo, with the type argument (int) substituted for each appearance of T in the template. Thus bar.data is of type int.

    The above example is, of course, not useful code. If you can't imagine any uses that are useful, learn C++ first (or contemplate what it would be like to write one linked list, and then use that one for the rest of your life on any data type you want). You'll eventually start to "get it".

  • I do BeOS programming as a hobby and think it is fabulous, but the system-level stuff isn't in C++. According to Be, it is about 95% straight C and 5% assembly. The programming interface, however, is a really well-designed set of C++ classes along with some C functions. It is really quite straightforward (and fun) to write GUI-based apps using these objects (usually your own inherited versions). For anyone interested in learning C++, I would highly recommend trying BeOS (especially since they are about to start giving it away for free). There was a Be newsletter article around the holidays entitled something like "Using C++ in the kernel" that explains why, in general, you can't write BeOS drivers in C++. It was way over my head, but it had something to do with the order in which libraries are loaded in the two languages.
  • by Anonymous Coward
    they do because they don't do a lot of gui work. systems programming can be done in c, and there is not reason to learn all the complicated stuff in c++ just for the sake of using c++. When you start working with gui elements and abstract interfaces you will quickly realize how tedious and unusable c is for that sort of work
  • by Anonymous Coward
    The best C++ learning book I've found is the C++ Primer by Lippman and Lajoie. It covers all the features and has simplified explanations with more detailed sections for those who want them.

    The Effective C++ series by Meyers is damn near essential. It was the first book to really explain why some things were done the way they are.

  • I think a discussion of Java would have also been somewhat redundant. He has made his views on Java fairly well known on several occasions, so asking him here would have been slightly pointless and would probably have been major flamebait too.

    Even so, you can pick up some of his attitudes towards java (or more generally, strict OO langs) simply based on the answers he presented here.
  • DDD is nice, but it (and probably ever other gdb based debugger) has the same problems with the STL as GDB.

    I would really like to see an answer to this question. IS there a way to skip over STL crap in GDB, or for that matter, ANY Linux-based debugger?
  • no, but I thought that was just another GDB add on. I think *anything* based on GDB would have the same problem.

    Might be worth looking at though...
  • by Anonymous Coward
    And the very first question of the lot:

    1) Has OO run out of steam?
    by rambone

    After 20-some years, it's obvious that object-oriented
    programming is not a panacea. What are your thoughts on the
    future of the OO paradigm? What other paradigms do you see
    challenging it?

    I can just imagine Bjarne's eyes rolling back, and then him taking a deep breath when he read this question.

    Thanks for wasting Bjarne's time with dribble.

  • One of the biggest problem with C++ is the lack of a featureful (freely available!) standard library to cover the range of things that Java covers (including the GUI).

    Obviously, that sounds like "everything and the kitchen sink" but at least you don't have to search days and night to find poorly designed/implemented libraries... And it can always be made "standard but optional".

    That is one of the reason why Qt is so popular: C++ is a great language when it has the appropriate libraries. But there is still some lacks as evidenced by the hack that Troll Tech has built.

    This is why the next big thing in OO won't be C++ but a free, efficient Java native compiler.
  • The fake interview *was* funny - but it wasn't a question...

    - Robin
  • So what you're saying is that even though he wrote this fairly large project single-handedly in C++, a) he does not know the language, and b) it takes more than one project to learn C++.

    Sheesh, that's enough to make me want to learn Java instead :-).

    -E

  • Something strikes me when talking to the two communities. C++ guys will talk about features of the "language" and will wax poetic on STL. Java guys will consider STL as "just another library" and in java's case java.util.Collection.*


    That's because the C++ language has an international standard, a component of which is the C++ library which includes the STL. So, effectively, the library is part of the language. Java isn't a standardized language; it's still at the stage where programmer are used to thinking of it in terms of specific tools and libraries.

  • I just want to say that I use MI much more often than single inheritance. I most often use inheritance to say that ``this object provides this protocol/interface/behavior'', and often have objects that provide more than one.

    I've also done this kind of multiple inheritance in C. I believe it's the most useful form of inheritance, and also the least kludgy and most genuine and elegant form of OO.

    Beyond being able to express interfaces, and dynamically bind interfaces to objects is the essence of object orientation. The ability to create a ``new kind of'' class with extra members, or overriden base members is just a handy kludge that sometimes saves work.

    Without MI, I would find the usefulness of C++ to be vastly diminshed to the point where I might as well be programming in C.
  • Innovation should focus on improvements and what works should be left as unchanged as possible. That way, people keep their existing tools and techniques and can develop from a base that is functionally complete. Also it saves the effort to re-invent the wheel and to teach "new" stuff that is equivalent to old stuff. Thus, C++ is as close to C as possible - but no closer.

    Or, in other words, "I strive for the mediocre." This is the Windows Way. Sure, Windows sucks (or maybe it doesn't). But in any case, it's a "base that is functionally complete" to use B.S.'s words. But Windows 2000 will be just like old windows, but it will suck less (or so they purport). The Linux Way is to find the best standard and then make the best implementation of it possible. This too is far from perfect innovation, but at the moment it seems to be working better for a lot of people.

    Stroustrop's attitude is what fails to challenge what needs to be. The questions should be "Is it acceptable that this is as slow as it is?" and "Does this really need to be as complicated as it is?" and "Why is it so difficult to get functionality x here?" C++ merely asks the question "What can we do with this and make it suck a little less?"

  • I prefer the

    code
    {
    //Stuff in curly braces
    }

    style myself,


    Java in a Nutshell, 2nd Ed, pg 118 (trying to blame JavaSoft people) - that went straight in one ear and out the other with me. They are talking about anonymous inner classes, but I won't break my own coding rules for this.

    ----------

    Exceptions - both you and joss seem to dislike the approach Java takes with exceptions. I happen to dislike the approach C++ takes. I've seen many resource and memory leaks in C++ caused by exceptions. Just the other day I found a memory leak in my code (well, Microsoft code - so my program) caused by an ODBC database exception, even though I caught and handled it immediately. I always declare the exceptions that are thrown by my methods - it's good documentation (a convention of CORBA that I like). I think C++ could benefit from forcing this and perhaps generating a low importance warning when not caught.
  • You didn't mention Java's crappy synchronisation techniques (that fits with your training language theory).

    For a language that boasts multi-threading, it can be extremely irritating try to express multi-threading techniques readily available in other languages. Mutexed object references just aren't fine-grained enough for me. Also, I can't easily test if a resource is locked and process appropriately. Is there any way of blocking until some other resource signals you to continue? I know, it can be done with the action listener approach, but that can get convuluted and overly complicated
  • Swing is getting better in 1.3, but too much of Swing is still under-specified. One problem with Swing is that all of the Swing objects are internally divided into a model and a view/controller, and a listener scheme is used to allow the view/controller to communicate with the model, and vice-versa.

    One problem with that is that when you register your own code as a listener to the activity reported by the Swing component, you are just another listener as far as the view/controller is concerned. There's no way to specify that your code's listener should be called before the internal model's listener, so you can't have your code attempt to verify a proposed GUI action and reject it if it isn't viable. At least, you can't do this reliably across different kinds of Swing components, because the level of detail on the components' behavior is not specified well enough. You can go and look at the source code for the component, but since the behavior you may be depending on isn't part of the spec for the component, you can't really rely on it.

    Not sure if that made sense, but basically Swing suffers a bit from the high level of complexity Sun put into it, and even with 1.3 it is still in need of more maturity. It is getting there, but Sun made their job a lot harder than it had to be by getting fancy with their pluggable look-and-feel support.

  • helped cull this mass down to 10 extremely high-quality questions

    The key word there is helped. Why not remove the obvious flames, if they are still scored at 5, and send the rest to Bjarne? I'm disappointed that my question got Score:5, managing to overcome being posted late (#260 or so), only to get scrapped because it wasn't thought worthy by the /. crew.

  • I believe the entire BeOS operating is written in C++, with an object oriented framework and a microkernel on which several "servers" handle system tasks.

    On the contrary, despite Be's C++ orientation, the kernel is written in C. Someone posted some relevant links [slashdot.org] when this issue came up while questions were being asked.
  • One comparison chart is at http://animal.ihug.co.nz/c++/compilers. html [ihug.co.nz]. Its a little out of date (CodeWarrior Professional is currently at 5.3, with 6.0 expected out later this Spring), but good detail.
  • One of the most ironic things about C++ is that it has made people aware that ++C is better.

    Why?

    Because if C has a constructor, then a C++ compiler has to create a copy, and to do that it has to call the constructor on the copy made by the C++ call in case there are side-effects. Which can be expensive But ++C does not create a copy. :-)

    Cheers,
    Ben
  • [Culled from a mail to PureFiction. Hope this explains more clearly
    what I was trying to say originally, and not lead to flamefests]

    I made a mistake by setting LilyPond code as an example, which has
    lots of historic baggage. And no, don't start about good design; the
    problem I set out to solve was much more complex than I could
    imagine. Trying to design stuff is relatively easy when the problem is
    well-known, and the requirements for the design are obvious.

    In this case, neither was. You just have to try writing something, and
    see how it comes out. Then comes the problem with C++: going along
    with the general popularity of C++, you write the prototype in C++; I
    did. As you go along and improve the program, you abstract things
    into new classes, and extend it while throwing away code. However at
    some point you reach rock bottom with C++: you can't abstract away the
    fact the C++ is compiled, and you can not generate code or treat
    classes as objects.

    It's probably been my error to start the program in C++ in the first
    place. That is the real design issue. And this kind of design issue
    is not treated anywhere in the C++ books. The language is not
    complete (in an abstract sense), which means that it limits you in an
    essential way in how you can abstract the code you write.

    It is my impression that the C++ committee is also faced with limits
    on the language, and continually extends C++. What I can't fathom that
    nobody concludes

    "Hey, backwards compatibility with C *and* full OOP support is
    too complex. Lets stop with C++ and start something new"

    but they say

    "great, lets bolt another thing on top of the standard."

    This was the real reason behind asking my question to Bjarne. Until
    someone questions the design principles behind C++, it will never
    stop growing more complex.

    Besides all this it just a pain to write tight code in the language. I
    tried to demonstrate this by showing a small snippet of C++. This
    also was a mistake, because I got an enormous amount of flak for not
    following other people's petty rulebooks. And lots of people here seem
    to think that mindlessly following rules constitutes "good
    programming" or "good design".

    Those are the two points that I want to make. Unfortunately, my
    rhethorical skills are less developed than my programming skills.
    Maybe I should post on /. more often :-)
  • First of all, I'd like to say that garbage collection is an extremely useful thing to have in a programming language. If you use C++ you can get Boehm's garbage collector which is described here. [hp.com] I use this collector and it works well for me.

    Now, having said that, I find that the Standard Template Library is the other extremely useful thing to have. G++ has a really great implementation (so sorry to you folks stuck on Microsoft VC++) that WILL make your life easier. strings, vectors, and hashes! Learn those and a few of the generic algorithms and you can attack most of your problems. The remarkable thing is that you can do gobs of stuff with STL without using pointers and mallocs at all! Seriously folks, if you're into C then you should check out C++ using the two features I mentioned. You will be amazed at what you can do. You most likely won't need to malloc your own memory. And if you do, you can rely on the garbage collector to clean it up for you.

    OK, I'm done. I just love C++ and since I started using the collector and the STL I love it even more.
  • Abstraction is your god.

    The advantage of well written C++ or well written code in general is the abstracted interface of functionality it provides. This gives the developer the ability to view and modify a system in an intuitive, abstracted manner. Back in the day of systems programming with C, this was done to a very small degree with libraries and such, but times change. Today's systems are growing larger and larger, and will continue to do so indefinately. When systems get large, the most valuable feature set to build within them is abstraction and scalability (closely related actually). For anyone who thinks C will always live, you may be right. It will always have its place for certain tasks. However, C++ will also have a very prominant position is future development as the need for powerful abstraction and flexibility is required in a language. (to some degree this includes Java and such, but this is a C++ thread)

    Abstraction!
  • Well, I claim, the lack of runtime safety in C and its descendants is a peculiarity and historical accident of those languages. I claim that there is no power you gain from it over alternative designs. The problem with C/C++ is not that they give you power, but that they don't give you the tools you need to ensure safety in those parts of a program where you need them.

    As for "with better coders, it doesn't have to be a problem", that may work for very well run organizations developing all their own code. And even for them, the required testing cost them plenty in time-to-market and testing resources.

    For the rest of us, who try to reuse commercial components and libraries, we simply don't have control over the testing that goes into the components we have to use. For starters, if you develop on Windows or Linux, you are already relying on millions of lines of source code that were developed with enthusiasm, but hardly the kind of quality control that ensures "no pointer errors in half a million lines of code". Quite to the contrary, both of those systems are known to contain plenty of pointer errors. And those errors can cause silent, serious errors, for example in a financial application.

  • There are indeed some safe runtimes for C and C++. However, they are not suitable for delivering applications. The kind of overhead they impose is considerably greater than runtime safety costs you in Java or other safe languages--you are better of using Java than using one of those runtimes.

    At the heart of the problem is that C/C++ don't have a standard way for programmers to specify information that is important for efficient runtime checks.

    In particular, in C/C++, the "pointer/reference" construct is used for arrays, references to local variables, call-by-reference, raw memory manipulation, format conversions, and some other purposes. But because you can't tell the compiler which of those you are intending to do, they compiler can't check for you efficiently--it has to check all the possibilities.

    This lack is a peculiarity of the C/C++ family of languages. It has nothing to do with power or lack thereof. You could add the necessary constructs to C/C++ without removing any of the power. C/C++ are simply deficient in a number of important language constructs. Java may lack template constructs, but C/C++ lack crucial typing constructs.

  • The same problems occur with Netscape plug-ins, dynamically loadable Linux kernel modules, native code Tcl extensions, native code Perl extensions, native code Python extensions, and a lot of other software.

    And if you think you can catch those problems reliably with a careful test of the binary code, you are kidding yourself. Very common kinds of bugs in those components (off-by-one errors, buffer overflows, changes to the floating point modes, etc.) can cause very subtle problems in other parts of the system. Without language/runtime suport, you won't find them, support that C/C++ doesn't have. And even if you could catch those errors, what would you do? Throw out the system-supplied standard libraries? the GUI toolkit you are using?

    BTW, I have written a lot of C/C++ code, and continue doing so. But that's for research and experimentation. For multi-programmer code that goes out the door, Java, Modula, Eiffel, Python, and other, safer languages are clearly vastly superior.

  • (looking over at the piece of paper, with a bunch of blobs, arrows, and such)

    So THAT'S why I feel so alone, sometimes, in liking C++.

    I just think differently from the C boosters, that's all. (I don't have the self-importance to say I think better :-)
  • Er, templates. Templates, like the force, are powerful, mysterious, and 3 people will give you 3 different descriptions and opinions of them. Let alone what 3 different compilers will give...

    typedef (*foo)();
    QList<foo> bar;

    bar += myfoo1;
    bar += myfoo2;

    for(unsigned i = 0; i < bar.count(), i++)
    bar[i]();

    I've never actually used a Qt list of function pointers before, but as far as I know, code like this should work.
  • If you need to pass some arbitrary argument to your function, it's perfectly trivial to write a single (one, only one, single, solitary, not plural, only one, the number between zero and two, as in ONE) function template that takes an extra argument and passes it to the callback for each item.
    .
    .
    .

    As I said about eight or nine times, you only have to write the function template once. ONCE.
    That's why you make it a template: So you only have to write it once. Can you count to one? Try counting to one. When you get to one, stop counting. That's how many times you will have to write the function template: ONE time.


    0++ ?


    ROTFL

  • I think he meant that you're blaming everything on the programmer, while ignoring potential problems with the tool (in this case, the C++ language).

    C++ is complex and cumbersome, and yes, a great deal of time must be invested in order to learn it. I can't help but wonder if that time would be better spent in more productive languages (Lisp, Dylan, Smalltalk, etc).

    Sigh...if only Gwydion Dylan [gwydiondylan.org] were more advanced, we'd have all the benefits of C++ (OO, speed, small executable size), without all the problems (the language itself) on Unix.

    ~~~~~~~~~
    auntfloyd
  • How about dynamically creating code, compiling it to native code on the fly, then calling it as a function? How about rewriting a running program from within itself? How 'bout doing all this portably? With just the standard language, no shell calls? How about an interactive C++ system? Show me a new class system for C++ which you wrote with no compiler modifications. How about macros? And no, I don't mean that lame text-replacement nonsense that passes for macros in C. I mean truly integreatied hygenic (sp) macros such as those in Lisp.

    Or even simple things. In Lisp, things like 'if' return a value. So things like

    (defun max (num1 num2)
    (if (> num1 num2)
    num1
    num2))

    Why can't I do this in C++? That's something I consider expressiveness. None of this unmodifiable 'statement' crap. If I want to rewrite the if macro, then by John McCarthy, I'll do just that.

    Do *that* in C++, and I might think about switching from Common Lisp. It's this sort of thing that makes me wonder if C++ programmers ever come out from their caves and wonder if there is a better way of programming than what they're doing now.

    ~~~~~~~~~
    auntfloyd

  • Yes, and your Borland compilers are out of date (3.0? That was in 1992!). I don't know what gcc version DJGPP uses, but I wouldn't be surprised if it didn't have all the latest C++ features just yet.

    And you might want to get Borland 5.5 [borland.com] sometime. Why not? It's free, as in Surge (Surge being preferable to beer)

    ~~~~~~~~~
    auntfloyd
  • rule based scripting languages such as Lisp, and scheme.

    Lisp and Scheme have a very important place in development, but most people tend to agree that its for configuration and similar issues. NOT system development, NOT application development.

    Well, it was a good troll up until now. Now I can't take you seriously at all. I actually thought you were a serious C++ user. You certainly sound like one.

    ~~~~~~~~~
    auntfloyd
  • Next question?

    Try doing everything else I mentioned. Or try passing a switch statement into a function call:


    (format t "the-var is ~a"
    (cond ((atom the-var) "an atom")
    ((null the-var) "null")
    ((numberp the-var) "a number")))


    C++ doesn't have the expressiveness of Lisp. Or the flexibility, which is why people don't like the way C++ restrains them. BS talks about how C++ can be used in many different programming paradigms, and he certainly lives up to his name. Try using something other than imperative OOP in C++. In Lisp, you can easily extend the syntax to support any style of programming: imperative, OOP, functional, logical, any more you care to think of.

    Why do you suppose it's been around for 40 years?

    ~~~~~~~~~
    auntfloyd
  • I don't look at it that way.
    It souds to me like he doesn't dwell on it! It was one of many projects he's worked on, and not somethign that defines his existence.

    When asked if he could go back and change anything, his answer starts with 'But you can't go back...'.. which is true.

  • I have to agree with what some of the other folks have been saying here. I first learned C++ (well, a shoddy mix of C and C++), and, especially as I've learned more about its features, I've found it painful to go back to purely-procedural languages. I've had to do tons of C in school, and it always leaves me wanting for the power of C++, Java, or even the convoluted object-extensions of Perl5.
    Of course, now we have Brian Kernighan here as a guest lecturer and he's trying to convert everybody to use awk instead. . . (great guy, though)
    --JRZ
  • Or maybe this is in the FAQ?

    It is, right here [att.com]. You should read it, it's worthwhile. In particular I like the quote "Java isn't platform independent; it is a platform." :)

  • I didn't know about the namespaces construct. I don't think it is exactly the same from what you said here.

    Abstract classes can indeed be used to imitate java interfaces. Yet there is a subtle difference: abstract classes may contain implementation whereas interfaces do not contain any implementation. This explicit separation between interface and implementation is very usefull. C++ can provide a similar mechanism (with a small performance hit) but does not enforce the separation.

    I protest against your qualification of Java as a 'dumbed down' language. I think it is a very smartly designed and elegant language.
  • I'm not sure I follow you on the subject of "resource leaking". I never experienced any problems in that area. Obviously you are unaware of the finalize method you can declare to do exactly what you want. The whole point of garbage collecting is that you don't need to worry about it. As a consequence you don't control when an object is destroyed. Rather it becomes eligible for destructions when there are no references to it anymore. A manual destruction would make java unsafe since you no longer can enforce that objects need to be unreferenced before destruction. BTW you can tell the garbage collector to collect the garbage when you need to do so but usually it is a better idea to let the garbage collector figure out a suitable moment to do so.
  • I don't see how the destructor mechanism guarantees anything since you still have to make sure it is called yourself. Rather I think that this is a major source for bugs in C++ (people forgetting to destroy an object or doing it too early).

    In Java it is typically a bad idea to release resources late (since A you don't know when the object will be destroyed and B you probably don't need the resource throughout the lifetime of an object. The try catch finally mechanism provides a great replacement since this captures the notion that using a resource is a bit like a trans action: book the resource, do your thing, handle possible errors, release the resource.

    The only problem that I detect here is that someone is trying to do C++ style programming in Java. While it works it is probably a better idea to adopt the java style.

    I think differences in programming style between Java and C++ are one of the reasons so many C++ to java porting projects fail. It's just sub optimal to program Java in a C++ style.
  • In Java, keeping a resource for the entire lifetime of an object is bad programming style since you cannot know for sure when the object is going to be destroyed or even when it gets out of scope (potentially a long time). That's why it would be bad style in Java to release resources in the destructor (you needlessly occupy resources).

    You are probably right about C++. Though I know some of the language I never bothered programming in it. I learned C when I studied at the university and I've seen a host of other languages as well (some very exotic). Anyway judging from your post you misunderstand Java as least as much as I misunderstood C++.
  • While I can't disagree with Stroustrup on that C++ might never have estabilished itself without the C compability, I getting more and more convinced that a good and clean language just can't have such historical burden to carry. Also, to be a clean language, C++ has too much awkwardness in its "advanced" features as well. I completely agree with the comment that the poor standard of C++ programmers is not due to poor education but to the complexity of the language. Programming in C++, too much effort goes into pondering the C++ syntax issues and compiler implementation problems.


    Don't get me wrong: C++ surely gets the job done, but I think it could be better and cleaner - mostly by removing some C compability and rethinking some other issues. Of course, this break the downward compability, and I'm pretty sure it'll never be done.


    One recommendation: try reading Stroustrup's D&E and Ian Joyner's Critique of C++ [uts.edu.au] in parallel.

  • <i>But you pay the same price as you would coding a C++ program - many lines of tedious coding, to get the less performance than perl can crank out of a program 10% the size. The gain must match the pain. Java's pain is equivalent to C++ - the gain is equivalent to VB. Where is the advantage?</i>

    If typing is your bottleneck when engineering software, you've got troubles. Program in APL if you must have the minimum text size. The facets I wre referring to was simplicity of design, elegance, etc.

    <i>You mean like trying to figure out which Java classes are synchronized and which aren't?</i>

    I agree there is no easy way to know which classes are multithreading safe and which aren't. The general convention has been to document it with the class (javadoc-style comments), but almost every language has the issue as well.

    <i>
    > It is almost difficult to make a Java program that is difficult to understand

    <br>That comment is idiocy, and you know it.
    </i>
    I'm serious. You <b>can</b> write crap code in Java, but it will still not be difficult to understand. Certainly much easier than C or C++ with pointer indirction and math, overloaded operators, etc. If I look at Java code, even if it's ugly, I usually still have a pretty good idea what's going on.

  • <i>Code length is directly proportional to costs and errors. This has been a well understood engineering principle for decades.</i>

    No, <b>complexity</b> is proportional to cost and errors. Longer code does not mean more complex, and often times the reverse is true.

  • I found the DDD that was mentioned in the original post - it's called the Data Display Debugger [gnu.org] and looks really interesting.

    However, it also appears to work with JDB as well as a number of other debuggers - perhaps that's what you meant in the original post when you listed nothing with it? Though from the original post it seemed to me you were indicating it was not availiable with Java.
  • I haven't been writing any C programs (except mandatory ones) for the last 3.5 years, and I don't think that C surpasses C++ for any real purpose.

    For programs of any size and of any choice I've found C++ to be the most expressive, flexible and efficient tool at my hand. For my stuff, "the worse is better" philosophy just doesn't work. Sorry Linus.

    From compiler writing to graphics, from combinatorial optimization to multithreaded protocol implementations, C++ proved to be the right tool for me. It did, because it is not a couple of ad hoc extensions over the C language. It is a new language, and a way better one.

    As far as I know, no other language comes close to the "multi-paradigm" features C++ offers, and with a most graceful treatment for efficiency.

    My advise is simple. Learn C++ in the true sense. First work through the language features with the latest editions of the wonderful books such as D&E or C++ Primer, and then proceed to the standard library to see *how it should be done* and to grasp *how to use the std lib*. The new ISO standard defines a language of power for any field. Don't forget that people who claim to know the language are quite a lot compared to the people who have comprehended it.
  • First off the interview was great. I'll be the first one to admit that parts of it went over my head (too many I fear... time to brush off the dusty old text books and review) but I also had another problem, I couldn't stop chuckling.

    Did anyone else keep picturing a large purple dinosaur as the 'mastermind' behind this new language designed, not to 'help everyone love each other' but to 'take over the world'. Yes... its Barney's evil twin (doesn't everyone have one?) Bjarne.
  • If you're up, around and posting to Slashdot, it's no wonder the officers were acquitted.

    Grim humor aside, police mistreatment of minorities is a serious issue. Your time would be well spent considering how you might do something more serious to address that issue than posting anonymously to discussions of object oriented programming, which serves only to make you look ridiculous.

  • I'm sorry, but did you read the interview?

    Ok, if you don't have time, let me point out the paragraphs that relate to your post.

    1.
    Naturally, you can write poor programs in any language. C++ is a powerful tool and in the wrong hands it can generate code that is *obviously* contorted and bloated. That may be preferable to the traditional spaghetti that poor programmers produce in C. Note that someone who is a good C programmer isn't automatically a good C++ programmer. Many problems have been caused by good C programmers assuming that they could adopt a semi-random collection of C++ language features and then magically become a good C++ programmer in a week

    2.
    C++ supports powerful techniques that are at best weakly supported by C and learning these techniques takes time. C programmers might do well remembering how long it took them to become "master level" C programmers. I see no reason why it would take less time to become a "master level" C++ programmer.

    3.
    Let me just mention something I wouldn't have done differently: compatibility. Had C not been there to be compatible with, I'd have chosen compatibility with some another language. Innovation should focus on improvements and what works should be left as unchanged as possible. That way, people keep their existing tools and techniques and can develop from a base that is functionally complete. Also it saves the effort to re-invent the wheel and to teach "new" stuff that is equivalent to old stuff. Thus, C++ is as close
    to C as possible - but no closer


    Basically, he is saying: treat C++ as a new language but I will base it off of one that is familiar. It is a true language, as for Java, that doesn't scale. C++ is a lower level language that incorporates OOP but with lower overhead and still keeps the speed of C. Java is best for high level apps (or applets) and C++ is good for the real programs.

    Steven Rostedt

  • ...for picking good questions and moderating down that old joke/fake interview about C++/job security and any questions associated with it.

    Moderation worked.

  • I'm amazed that no question regarding his opinion on Java didn't make it through moderation.
    I'm sure it scored highly - but when you are limited to ten, it's difficult to select such a small subset to give from such a wide pool of possible queries.
    One point I did find interesting was the statement that he "peeked" at the raw questions on /. - and wondered if it would be possible to have a more interactive layout for this - maybe even convice some of our potential questionees to take part in the initial trawling and guide some of the comments with short replies. Does he feel Java is a competitor? or just another implementation to solve a different set of problems (e.g. web-programming)?
    I am slowing learning this too <grin> but also see it as aimed at a different set of problems - one where compatibility and visual effect is more important than power and scope. I could be wrong of course :+)

    Or maybe this is in the FAQ?
    Not that I have ever seen.
    --

  • Elegantly said. C++ is a little tougher and takes a little effort to learn. The key word being effort. As a PHB I've found that developers who write marginal code in C did write poor code in C++, however I think this comes down to both a person who uses tools and resources targeted to meet a specific purpose and people who stay whith what is comfortable to them reguardless of the fact they may be using the wrong tool for the job.
    Guilty as charged <grin>. I have largely ended up writing C code thinly disguised as C++ for years - not really due to comfort or singlemindedness though, but due to the fact I can write decent C, and if I had to suffer through my C++ puppyhood in a production environment, my job would be on the line. It took me four or five years to learn to write decent procedural-language paycode - and how many employers are willing to have an employee currently producing usable code effectively not there for that length of time?
    --
  • I can just imagine Bjarne's eyes rolling back, and then him taking a deep breath when he read this question.
    I can see how the style it was written in (confrontational and almost a direct attack) could be a little daunting, but there *is* a important question in there, and I think he made a game attempt to answer it - what it comes down to is "How tied is C++ to the OO methodologies, can it evolve to whatever is or could replace it in the near future, and if it can, in what directions would you expect it to evolve?"
    --
  • Odd, one of the problems I've seen is that lecturers concentrate on the C++ aspects of C++ too much and give the C aspects short-shrift. The biggest problem I see in day to day coding maintaining stuff written by people who are poor C++ coders is overuse and misuse of the advanced parts of C++. If I had a nickle every time multiple inheritance was used unneccesarily...
    I've obviously been away from Academia too long &ltgrin> - When I learnt C, C++ was still in it's new, shiny wrapper, and most of the lecturers were obscessed with Pascal anyhow :+)
    --
  • When we did, we looked for C++ developers and stopped the pain, and increased the quality of our code overall.
    Hmm. I hope this doesn't become a problem for those of us still using C rather than C++ - we may find ourselves pushed out of our current jobs as the job spec changes to requrire C++ skills our employers aren't willing to support our retraining on....
    --
  • First of all, since C++ is a 99% superset of C (that is, almost all C code including variable length function arguments is also valid C++), arguments like "C++ lets you do less" are not valid. Anything you can do in C, I can do in C++ in exactly the same way. As for untyped functions (I'm not familiar with that term, but I presume you mean functions with no prototypes), just spend a few extra seconds to write a prototype for every new function, it will save time in the long run; and I don't see how it "weakens" the language.

    The complexity of C++ is a valid argument and I agree that the simplicity of C is one of its major strengths.

    However, I think by blasting "abstraction" is general, you are missing something that is fundamental to *all* programming, not just OO. For example, the concept of "function" is an abstraction. After all, "goto" is much more like the computer *really works* than insane abstractions like loops and organised blocks of code. Why should programmers waste time learning useless bloated things like that? So, assembly language is clearly superior to C; asm is much more simple and direct. COMPUTERS ARE NOT STRUCTURED; NEITHER SHOULD PROGRAMMING LANGUAGES BE.

    You can see how silly the preceding argument is :). Well, after learning OO, the discourse from structured-paradigm programmers sounds strikingly similar. After a while, thinking of things in terms of objects becomes just as intuitive as thinking in terms of functions, and you don't want to go back. If you explore OOP, I think you will find that it is beautiful.

    Most C++ programmers have lots of respect for C; after all, it is half of our language. Perhaps before being disrespectful to C++, you should learn more about it.

    Broccolist
  • You said:

    "Packages [in Java] can be nested and the package is part of the class name (which makes it possible to have class names with the same name in different packages)."

    It's the same with namespaces in C++:

    namespace Foo {
    class Bob {};
    }

    namespace Bar {
    class Bob;
    }

    Namespaces can also be nested. They're not quite the same as Java packages (namespaces are strictly a logical concept, and can be spread across several files), but still they are very useful.

    Personally, I enjoy coding in C++ more than Java, mainly because of templates and the STL. The STL really changes ones approach to programing. Java's lack of template is a significant omission to me. I also appreciate the static type checking in C++. I don't see what the big deal is with interfaces vs. abstract classes -- they are equivalent concepts.

    It seems that your argument is that people who don't know what they are doing can screw up worse in C++ than they can in Java. This is probably true, and I can see why corporations would prefer a "dumbed down" language. But, I do know what I'm doing, and I prefer using a language that gives me lots of options.

    My biggest gripe with Java is that is proprietary. I prefer using a language that isn't controlled by a single company.

    The biggest problem with C++ is the way that most programmers use it -- using c strings instead of std::string, c arrays instead of vectors, etc. This is a matter of education.

    Steve Molitor

  • Well, come on, PPJ, you have to tell us now. What are the languages that you refer to that are not abominations and crimes against nature? Restrict your answer to languages that are actually useful, and meet your criteria of OOPed, more compact, more consistent and less confusing, while encouraging better programming discipline. Otherwise your comment is just hot grits. I ask this question in genuine curiosity and without sarcasm.

    "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off."
  • Thanks! I will look up info on Oberon.
    Interesting point about Wirth languages getting smaller. That's also an interesting sequence you drew there. I didn't even know there was a followup to m/2 from Wirth. Is it actually a followup or a new thread? Wirth might argue pascal doesn't belong in the same room as m/2 -- what did he say, something like "it's an instructional language, stupid!" cheers z

    "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off."
  • I agree with you that it's a pain to have to do a cast on something the compiler ought to have figured out can't cause a type safety violation. Type polymorphism (ie, templates) is definitely the biggest thing missing from Java. Fortunately, they're adding it [sun.com] (see? [sun.com]). In fact, there's already an compiler [bell-labs.com] that will do it- it's just not Sun-blessed. (But the .class files that GJ spits out are ostensibly bytecode-compatible with regular java, so no special JVM is required to run them.)
  • I'd suggest reading a few books on object-oriented design, and on best practices in C++. Books that have worked well for me are: C++ FAQ's, Design Patterns, Object Oriented Software Construction, Effective C++ and More Effective C++. I was writing 10's of thousands of lines projects before I really learned how to use the language properly too. Don't be fooled into thinking that just becuase you've managed to write a relatively big project you know everything

    The fact that someone who manages to write a tool like Lilypond (can't be an idiot), and also yourself, has to read lots and lots of books and learn through writing 10's of thousands of lines on how to really use the language, is not a good sign.

    As for myself, I have about 5 years of exp. with C++ and two years now with STL. It is a big improvement (STL), I can write nice programs in C++ after all these years. BUT: I think it takes too long, and average people may never make it to understand the language and use it effectively.

    Currently I'm using Java, swearing a lot and longing back for C++ often. Still I'd really like to try Phyton or Scheme once. There must be an easier and more fool-proof way to do the nice things that can be done in C++.

  • As Bjarne once said, Smalltalk is the best Smalltalk around. And ObjC is just C that tries to be Smalltalk.
    --
  • Yes, it is brain-dead. I could write a "C--" language which only used the "." operator. Using type analysis in my context-senstive analysis, I could replace the "." with a "->" when necessary, and output code that a normal C compiler could generate.

    So why does C have a "->" operator anyways? Because it's brain-dead.
  • I think the difficulty in new users learning C++ is the inability to read Bjarne Stroustrup. Seriously, I have had his 3rd edition book for about 6 months now, and I have yet to be able to figure out the first couple of chapters. It has now become an issue of pride that every opportunity I get, I try and understand still yet another paragraph (good bathroom reading material). His writing style is definitely geared towards a technical, engineering personality.

    I realize most of these questions were not directed at newbies, most of those questions were answered in the FAQ, but just reading Bjarne's thoughtful responses gave me flashbacks to the bathroom this morning. :-)

  • One of the UNIX C compilers in my lab (I forget which UNIX) apparently doesn't guarantee a return of 0 unless you actually return 0. This dinged me for a few minutes when I was checking the return code from a program.
  • Obj-C has advantages and disadvantages with reference to C++. I used a NeXTstation as my primary development platform 1992-1995 and became intimately familiar with Obj-C. Its elegance comes from the inclusion of only a minimal set of OO features - there's no multiple inheritance, no template classes, all object access is accomplished via reference variables (pointers), there's not even a public/protected/private distinction (everything is effectively protected). This greatly simplifies the resulting code. The object syntax, while elegant, is borrowed wholesale from Smalltalk and therefore looks somewhat strange when mixed in with C syntax. C++'s object syntax is definitely more consistent with its C origins. Also, Obj-C relies heavily on "run-time magic," which Bjarne specifically sought to avoid in C++. This dependence can increase the elegance of your source code at the expense of performance.

    Part of what made Obj-C so pleasant to use on the NeXTstation was the rich object class library that NeXT developed. My big indictment of C++ is its lack of such a library; the STL is nice, but it's only a small part of what we need. I think C++'s wide installed base actually hinders such an effort to a great degree. Java's JFC/Swing libs are certainly rich but somewhat strangely organized.

    Neutron

  • Not meaing to go completely off topic, but I will anyway. This is one of the reasons that I think that there will always be a place for commercial software. There's lots of stuff that is just boring, complicated, and generally a pain to program- ie stuff that no one is going to do for fun, like getting gdb to wade through the STL symbols output by gcc and display them intelligently. Dollar signs have a way of overcoming these little shortcomings.
  • Naturally, you can write poor programs in any language. C++ is a powerful tool and in the wrong hands it can generate code that is *obviously* contorted and bloated. That may be preferable to the traditional spaghetti that poor programmers produce in C. Note that someone who is a good C programmer isn't automatically a good C++ programmer. Many problems have been caused by good C programmers assuming that they could adopt a semi-random collection of C++ language features and then magically become a good C++ programmer in a week.

    Elegantly said. C++ is a little tougher and takes a little effort to learn. The key word being effort. As a PHB I've found that developers who write marginal code in C did write poor code in C++, however I think this comes down to both a person who uses tools and resources targeted to meet a specific purpose and people who stay whith what is comfortable to them reguardless of the fact they may be using the wrong tool for the job.

    The interview questions were very good, Glad to see the good ones get bubbled up to the top. Also thanks to Bjarne Stroustrup for taking the time to answer them fully and completely, it's obvious that he spent some time with this.

  • Speed of execution isn't always important.

    But you pay the same price as you would coding a C++ program - many lines of tedious coding, to get the less performance than perl can crank out of a program 10% the size. The gain must match the pain. Java's pain is equivalent to C++ - the gain is equivalent to VB. Where is the advantage?

    Yes, generic programming, multiple inheritence and operator overloading are things that can be beneficial sometimes. But it also means it is harder to understand what is really going on.

    You mean like trying to figure out which Java classes are synchronized and which aren't?

    At least C++ is trying to sneak something under your nose.

    It is almost difficult to make a Java program that is difficult to understand

    That comment is idiocy, and you know it.

  • I've met many a programmer who thought that the "idiot-proof" approach take by Java was going to get them to a paycheck faster than other tools.

    Man, were they wrong.

    First things first - Java is not "write once run anywhere". You can choose to believe the Sun hype, or you can try it out for yourself. If you develop anything useful with Java, you will not only be supporting various platforms (tough with no preprocessor), but you will also be supporting different version of the JDK! Yes, thats right - Many developers have to force users to adopt one JDK version in order to get the damn thing out.

    I'm glad that Java worked out for you - I know many programmers that have shipwrecked many a project by using it.

  • Since Java was released less than 5 years ago

    JDK 0.9 was released for "use" to the public more than five years ago - I know - I used it for my grad project when I was in school than.

    The requirements of the embedded, standalone market closely match those of a networked, distributed world,

    That doesn't make any sense at all.

  • If typing is your bottleneck when engineering software, you've got troubles.

    Code length is directly proportional to costs and errors. This has been a well understood engineering principle for decades.

  • Something strikes me when talking to the two communities. C++ guys will talk about features of the "language" and will wax poetic on STL. Java guys will consider STL as "just another library" and in java's case java.util.Collection.* but will talk about the API's, software design, extreme programming, and the high level libraries.

    In my case EJBoss is based on many 3rd party libraries (BullSoft, IBM, SUN, W3C, Apache, Dreambean, Telkel). That REUSE is possible given that java comes with bytecode format and a DEFACTO ABI..

    This to me is the main difference between the two class of people. One is "stuck" at the language layer, and the only interesting discussions will be on compilers ( i am not saying they are not deep just that they are stuck in a "low level" language world). The other one is REUSING libraries and discussing software functionality. The design of large sofware frameworks is based on this. OOP Reuse is REAL in java and seems non-existent in C++ due to the lack of ABI. Please turn off the light in the C++ camp, as this to me is the future of programming i.e. online component based development.

    marc
  • More likely the fact that C++ tends to be taught by lecturers more familiar with C. I suspect better training for lecturers would result in better training for students :+)

    Odd, one of the problems I've seen is that lecturers concentrate on the C++ aspects of C++ too much and give the C aspects short-shrift. The biggest problem I see in day to day coding maintaining stuff written by people who are poor C++ coders is overuse and misuse of the advanced parts of C++. If I had a nickle every time multiple inheritance was used unneccesarily...

  • I do not presume to know Bjarne's motivation but I do disagree with your judgement of people plugging their work. Have you noticed that people do the talk show circuit only when the have a project to sell. Do you distrust them for this. Talk show, book signings, taveling to a conference to give a talk, all the same thing. I found the way he pluged his papers and books very comforting. He's just a guy (bright and talented) that is working for a living and has produced some stuff that he is proud of and is rewarded for financialy. That makes him seem more real to me.
  • by Davorama ( 11731 ) on Friday February 25, 2000 @08:37AM (#1246246) Journal
    These other questions were so great I didn't make the cut but maybe you folks have opinions you'd like to share?

    What do you think of template meta programming? Do you consider it a boon, enabling clever programmers to do outrageously cool things like the Blitz [oonumerics.org] project? Or is any benefit derived from it's use washed away by the obscure, nearly unreadable code it takes to implement it?

  • by Venomous Louse ( 12488 ) on Friday February 25, 2000 @10:32AM (#1246247)

    In an ideal world, all the code one uses would use the same string class, and all the old C libraries one links with would be rewritten in C++ and available in source form so you could compile it yourself and not have to worry about name-mangling and whatnot. On earth, we're stuck with legacy code that uses its own string classes, MFC (pray for us poor sinners) which uses their own (broken) string class, and OS API's (and other C libraries) which use char * and various typedefs thereof. We should probably all be using std::string, but I've found it sort of perplexing the few times I've bothered with it. In any case, it came along so late in the game that other string classes had already proliferated and are now immortalized by bassackwards compatibility.

    However, all of these string classes have some way to get at their char *'s, and they'll all construct from char *. So char * is a sort of lingua franca or least common denominator that lets us work with all this inconsistent crap and still get code written. It's a bummer, but it's better than nothing.

    I think the first thing Stroustrup should've done by way of C++ libraries was write a good solid string class while CFront 0.1 was still wet from the womb, and proselytize it endlessly. Of course, if he had, ten years later we would've ended up with a standard string class inconsistent with the rest of the STL. Oh, well. You can't have everything.

  • by jetson123 ( 13128 ) on Friday February 25, 2000 @12:11PM (#1246248)
    It's sad that Stroustrup didn't get a chance to talk about safety and fault isolation. I believe that lack of those features is a fundamental problem in the C family of languages and causing a lot of the most serious problems with computers today. What are some of them?

    • Many (most?) security holes in clients and servers are due to buffer overrun problems: the Morris worm, bugs in Netscape and IE, bugs in IE, bugs in most Internet protocol daemons (sendmail, bind, etc.). These are entirely avoidable with almost no runtime cost.

    • Component based software (browser plug-ins, COM/ActiveX components, Perl/Tcl/Python plug-ins, etc.) crash their hosting applications, often without even a clear indication of which component caused the system to fail.

    • Many programs contain pointer errors and corrupt memory without crashing, resulting in incorrect results or incorrect behavior that often goes undetected for years. Even when the behavior is detected, it often can't be traced to the component that is causing it. This is a particular problem when software is reused, because the reused components are developed with unknown quality control measures and safety design methodologies.

    Most people seem to have come to accept the fact that their word processor, browser, and operating system crash with obscure register dumps with some regularity. But to a large degree, many of those problems are the heritage of some old design decisions in the C programming language, inherited by C++ and Objective-C. In fact, I think many of the serious problems we have with computers can be traced to lack of support for fault isolation and runtime safety in the languages we use, either directly (programs crash/have security holes) or indirectly (time that could go towards improving software needs to be spent on unnecessary testing/debugging).

    It isn't very difficult to come up with a programming language that is like C (or C++ or ObjC) but also provides support for runtime safety and fault isolation. You don't need to sacrifice any efficiency or systems programming features. But C++ has, so far, dropped the ball on this. Some of its abstraction facilities (e.g., the "string" class) alleviate some of the problems if used properly, but there are no guarantees you can make about any piece of C++ code, and even if you are careful, you can't avoid unsafe constructs in code that ought to be safe.

    That's why Java is catching on. Java may be lacking templates, systems programming support, multiple inheritance, and lots of other features. Java is also slow and heavy by comparison to C/C++. But Java does provide fault isolation and runtime safety, and in the end, that is what matters most to application programmers that need to get out reasonably reliable software on a tight schedule.

  • by SuperKendall ( 25149 ) on Friday February 25, 2000 @02:57PM (#1246249)
    A response to some of your issues:

    I prefer the

    code
    {
    //Stuff in curly braces
    }

    style myself, but have always hated underlines - almost all of the Java programmers I've met use this style. I can't agree with you about the use of "_" as a name seperator, which doesn't look appealing to me and seems like a waste of space (while on the other hand, I do prefer reallyQuiteVerboseNamingOfMethods(). I never claimed to be rational myself!).

    I don't really think the other brace style is widespread, at least not so much so I'd call it any kind of "standard" that gets in your way.

    ------------

    Exceptions - I agree with you, in that a lot of times it's more useful to have a low level exception that is meant to be caught a few levels up. You don't have to have a subclass of error for that, just RuntimeException. These are unchecked by the compiler and require no declaration in the methods that throw them.

    I've used exception systems based on runtime exceptions before and they worked really well. You could catch the exception where you cared about it, and we had a general framework that would catch any left-over errant exceptions and deal with them there.

    --------

    Slowness of Java. What you need to do in Java, is take care to optimize really important stuff (or even marginally important stuff) carefully.

    I agree with you that many of the libraries (including Swing) have some marginal implementations - but at least Swing is generally flexibale enough that you can write a really efficient replacement if you need to. I always argue that Java is much quicker to write new stuff in, but you must use some of that time near the end of a project to analyse problems with efficency and make repairs as needed. It just happens that it's generally also a lot easier to make the performance improvements.

    ------------

    Language features:

    Templates: I won't argue with you here, they may be of use, and might eventually be added to Java. But I do have to say they make for some pretty horrific looking code.

    Enum:

    A type-safe enum like construct in Java:

    class ColorEnum
    {
    private ColorEnums(String enumValue){}

    public static blue = new ColorEnum();
    public static red = new ColorEnum();
    public static greed = new ColorEnum();
    }
    ...

    if ( currentColor == ColorEnum.red )
    {...
    }

    MI:

    I would argue that if interfaces are a subset of MI, they represent the useful subset :-). I personally have not missed MI.

    PreProcessor:

    Well, if you really feel a need for preprocessing, why not use m4 and just add macros anyway? I worked ona project that spanned nine different UNIX systems, as well as VMS and MPE, so I became pretty familiar with just about anything a macro could do. This is another feature I do not miss, and have not felt the need for.

    Operator Overloading:

    This and the dislike of verbosity are really two facets of the same problem. I personally like a more verbose style of coding that loos like fred.elementAt(i) instead of having fred[i] pull elements for me.

    I can't say I find it true that Java tried to make everything safe for the programmer - it gives you plenty of rope to hang yourself with, just like any other language. It's just that the rope looks a lot different and is kept in different cabinets.

    ----------------------

    Verbosity

    Here, I have to disagree with you - but this is of course a purley subjective thing. I can't really say that your dislike of really verbose names is wrong any more than my own liking for them is right. I just know what I like.

    However, I do think your example is unfair. You use a nice map, and the iostreams stuff that's built in. In the same fashion, Java has many built in libraries that are of similar use and are also going to be there for you if you need them.

    Even if you have to resort to a third party library for some need, you know that if you can find one there will be no porting work to be done, you can just use them... in a test of any complexity above adding two numbers, you are probably going to be pitting libraries against each other.

    I would say it would be more interesting to produce some interesting piece of code that uses tenplates and then try and see how it could be done in Java. I'm going to take a look at the Blitz package you posted, it sounded rather interesting.

    ---------------

    Libraries - I'll skip this one for now. I agree with you on Swing though that they should have focused earlier on performance and stability. It's really nice to work with, though.

    ---------------

    Printing - I don't think it's quite that way anymore (though I haven't done printing for about a year). So, I basically don't really know what I'm talking about here and will go on to the next topic...

    ----------------

    Tools:

    javac - with make. Why not use Make? You always need Make.

    jdb - almost usable in Emacs with JDE... other graphical debuggers are nicer. At least they have an open API for debugging now, but I agree that doesn't help you now!

    Visual C++ vs. NetBeans is more interesting. I'd agree with you about JBuilder or Visual Cafe.

    DDD - admittedly unfamiliar with this.

    purify vs. OptimizeIt - I've used purify and while OptimizeIt is not quite as nice, it's pretty close.

    quantify vs. JProbe - I think you still have this one.
    ---------
    Sorry for any spelling errors or just plain idiotic mistakes above - I had to type in a hurry.

    You want a real rant? How about FIXING THE SUBMISSION BOX so that "Extrans" and "Plain old Text" are not reversed. I hope I am not corrupting the database too much by doing all my "extrans" posting with the "Plain Old Text" option selected...
  • by tdrury ( 49462 ) on Friday February 25, 2000 @08:32AM (#1246251) Homepage
    I'm amazed that no question regarding his opinion on Java didn't make it through moderation.

    Does he feel Java is a competitor? or just another implementation to solve a different set of problems (e.g. web-programming)?

    Or maybe this is in the FAQ?

    -tim
  • by DaveHowe ( 51510 ) on Friday February 25, 2000 @08:28AM (#1246252)
    Wow! Can he do no wrong? I guess there's just nothing wrong with C++ at all. There's nothing that could have been better implemented.
    I think this is far from a problem - what he is saying is that anything he saw as being wrong he has fixed or is fixing - If someone builds a tool, and it is perfectly suited to his hands and his reach, then you also use that tool, and find it less well suited, it just means you are different to him - not that either of you are "wrong" in some abstract sense.....
    --
  • by LordEq ( 63011 ) on Friday February 25, 2000 @09:03AM (#1246253)
    > I was looking for some reference to "I wish I
    > had done that better" or something.

    "I think my most obvious mistake was not to introduce templates before multiple inheritance and not to ship a larger library with Release 1 of my C++ compiler."

    "I, and the standards committee, underestimated the importance of templated typedefs. My guess is that they will be added in the future."

    "I guess that in this case, my reluctance to add new features without a clear practical need caused problems."

    "I underestimated the linker problems. I may also have underestimated the problems stemming from C compatibility."

    There you go.

    --LordEq
  • by MikeyO ( 99577 ) on Friday February 25, 2000 @01:20PM (#1246254) Homepage
    For instance a fragment of a C++ program that reads in a file and gets a list of the starting positions for every word in the file:
    map > word_positions;
    string word;
    while (cin)
    {
    cin >> word;
    word_positions[word].push_back((int)cin.tellg() - word.size());
    }
    Writing the equivalent in Java would take 20+ lines

    Heres a java object to do this.


    import java.io.*;
    import java.util.*;
    public class TokenizeStdin extends
    BufferedInputStream
    {
    TokenizeStdin( Hashtable wordMap ) throws IOException
    {
    super( System.in );
    StreamTokenizer strTok = new StreamTokenizer( this );
    while( strTok.nextToken() != StreamTokenizer.TT_EOF )
    {
    if( !wordMap.containsKey( strTok.sval ) )
    wordMap.put( strTok.sval, new Vector() );
    ( ( Vector )wordMap.get( strTok.sval ) ).addElement( new Integer( pos - strTok.sval.length() ) );
    }
    }
    }
    This in not a snippet! This is the whole shebang. If the above C++ comment were expanded to make it compile ( the java version will compile as is ) it would be as long as my java version. I agree that the Java version is not as pretty, but that is mostly due to the fact that the java container classes have not reached the level of maturity that the Standard C++ containers have, yet. But remember that for the first 8 - 10 years of C++, templates were not available, and there were no Standard C++ containers. People are working on adding templates to java. See gjc [bell-labs.com]. Once this has reached maturity, good templatized container classes can't be far behind.

  • by Julian Morrison ( 5575 ) on Friday February 25, 2000 @09:54AM (#1246255)
    From my way of seeing it, ObjC is way more similar to smalltalk or perl than it is to C++. So much is resolved at run time - and quite a lot is also left to programmer discipline. Coupled with the Foundation library, it can do neat tricks like opt-in reference counting, simple clean distributed-objects without ugly hacks like CORBA, and building "selectors" (function identifiers) at runtime and calling them on arbitrary objects. Plus, it's proof against "fragile base class" except with instance variables.

    ObjC's attitude reminds me of perl: "You wanna do something wierd? Your program, your problem; don't let me stop you."

    I'd pick ObjC over C++ any day for everything except kernel bit-twiddling or projects needing huge-scale multiparty co-ordination, but if I had my way I'd add in proper exceptions and some java-like threadsafety primitives.
  • by grappler ( 14976 ) on Friday February 25, 2000 @08:44AM (#1246256) Homepage
    I believe the entire BeOS operating is written in C++, with an object oriented framework and a microkernel on which several "servers" handle system tasks. It is by no means slow or bloated. Of course, for R5 they are scrapping the Net server in favor of one more closely tied to the kernel to improve performance, and I think they're doing something similiar with 3d acceleration.

    Anyway, the point is, they use C++ for system level stuff and it works great. Of course, the Be people are by no means "old dogs". There is nothing legacy about BeOS.

    --
    grappler
  • by sethg ( 15187 ) on Friday February 25, 2000 @09:12AM (#1246257) Homepage
    A common theme in the answers seems to be "that complaint is based on outdated information; get a new compiler that follows the standard and use the STL."

    For the benefit of us C++ newbies, does anyone maintain a chart showing which currently-available "C++" compilers violate which sections of the C++ standard?
    --
    "But, Mulder, the new millennium doesn't begin until January 2001."

  • by jilles ( 20976 ) on Friday February 25, 2000 @10:09AM (#1246258) Homepage
    If you look back in this interview, you'll notice that bjarne has very clear ideas about how multiple inheritance should be used. If you compare that to what Java supports you'll find that it actually supports this type of usage (namely multiple inheritance of interfaces). The problem with C++ is that it has no first class representation of interfaces (which is why you need multiple inheritance of classes to imitate this feature). Java has support for interfaces built into the language so it can prevent people like you shooting theirselves and the companies they work for in the foot by abusing MI. If you are still sceptical about this, I would like to point out that there have been empirical studies about the use of multiple inheritance and these studies make it pretty clear that the use of MI for inheriting code is a bad idea in most cases.

    I don't really see the point of having operator overloading. The advantage of being able to overload them is fully consumed by the resulting confusing code. I don't want my + operator to be overloaded. I don't want to work on code where I have to look up what the + operator actually means. If assumptions I have about such simple things as + and - no longer hold true I can't do my work properly.

    My main problem with C++ is not that it lacks features but that provides to much of them. Java as a language is much simpler and the only problem I see with it is that it doesn't have support for templates yet. On the other hand there are many features in it that you only get in c++ if you are a skilled and disciplined programmer. Take for instance a simple concept: package. The package construct allows you to group classes into packages. Packages can be nested and the package is part of the class name (which makes it possible to have class names with the same name in different packages). Of course this simple feature can (and should) be imitated for large C++ projects but its just not as straight forward as in Java. Another feature is that Java assumes that your functions are virtual rather than static (as in C++). C++ obviously can't do this without breaking compatibility with C so OO programmers are doomed to type virtual in front of every method they declare.
    Another thing is the C compatibility. I don't see the point of it. True, in isolated situations it may be handy to be able to quickly port old C code (but then why not redesign it while you are at it?). In most situations though you are better of resuing the old code base in the form of libraries (as you do in Java with native methods).

    These little, well designed language features make life easy for a programmer. And that's exactly what a language should do. C++ programmers always complain about lack of features in Java but this is in sharp contradiction with actual productivity of programmers using C++ and Java.

    Also the fact that C++ is so close to C prevents it from doing certain optimizations (according to Bjarne in this interview). I'm not in favor of a one size fits all language. Especially if that means making compromises all over the place. C++ is one big compromise towards C compatibility and performance. In many projects C compatibility is not essential or even redundant and performance is not the primary quality requirement. C++ therefore is not the most suitable language for this growing category of projects.

    In many cases using C++ makes your programs needlessly complex and confuses the programmers. True, if you no what you are doing it can be a handy tool but unfortunately many programmers are not in that position.

    In the interview I noticed some frustration with the fact that there are still hordes of programmers using C (for non valid reasons). I feel a similar frustration towards the use of C++ and Java. True there have been and there are performance problems with Java. But just like most of these issues resolved with C++, most current issues with java will be resolved over time.
  • by SheldonYoung ( 25077 ) on Friday February 25, 2000 @09:32AM (#1246259)
    There are some decent arguments in there. However, you're arguing the wrong points. That language wasn't design to be either fast or feature-rich.

    Speed of execution isn't always important. There is such a thing as "fast enough". Often the speed at which a developer can write an application is more important than the speed at which it runs.

    Feature-rich is another pitfall. Yes, generic programming, multiple inheritence and operator overloading are things that can be beneficial sometimes. But it also means it is harder to understand what is really going on. Is [] just an array or is an overloaded operator that makes some non-obvious assumptions? With MI if I hadd something to one of the base class, what happens - especially if there are conflicting names?

    Consider this: It is almost difficult to make a Java program that is difficult to understand, unless the design is really, really bad.
  • by mav[LAG] ( 31387 ) on Friday February 25, 2000 @08:18AM (#1246260)
    ...came up at me like this:

    Why no single programming language can solve every need. By Bjarne Stroustrup
    The Red Herring magazine
    From the April 1999 issue
    Why would investors or executives care what programming languages their companies use? After all, customers don't care, and shouldn't. When I dial an 800 number, I don't stop to consider which language was used to write the program that translates it into the number of a phone on someone's desk. But software is crucial to the products and services we deliver -- and the programming languages we use to write that software can make the difference between success and failure.

    [an error occurred while processing this directive] LANGUAGE ARTS
    A good programming language allows programmers to express the ideas of an application simply, directly, and affordably. It gives programmers who want to improve on a program a decent chance of grasping the structure of the system. This is critical for a software development organization's effectiveness: a programming language that makes the structure explicit helps engineers and makes it easier for software tools to analyze and display programs.

    I'm not sure that the programming language used to write the software that generated this page has made that difference between success and failure :)

  • by adubey ( 82183 ) on Friday February 25, 2000 @09:19AM (#1246261)
    (Refering to the post I'm replying to).

    In my experience, much of the unavoidable complexity of C++ comes from the fact that you can use either pointers or references to refer to objects.

    Note the distinction between "unavoidable" complexity and the avoidable complexity of templates and multiple inheritance - often you can't get around this.

    References are nice because the "->" operator is brain-dead: why should the programmer keep track if something is a pointer or not when a type-safe compiler can figure out if "." or "->" is suitable.

    But references, unforutnately, can't be used everywhere. The lack of an ABI might be one reason. The fact that Linux/Unix only has 'C' style interface is another, related reason. (NB: Windows _does_ have MFC to abstract OS functionality, if you want it. From what I hear, it doesn't abstract that functionality very well, though...).

    But you sometimes have to mix pointers and references for the simple reason that you can't re-assign references. In code, this might be no problem, but what about classes?

    Another unavoidable complexity deals with the language's decision not to have proper "interface"/"implmentation" files. On one simplistic level, it means I have to unnecessarily type in:

    #ifndef __MY_HEADER_H__
    #define __MY_HEADER_H__

    ...

    #endif

    But there are other annoyances. For example, you can't statically initialize static member variables! To be honest, you can, but not the way that a programmer would naively expect:

    class {
    static int foo = {1,2,3,4};
    };

    just doesn't work.

    Things like this are the gravest error a language designer can make: if the language doesn't work in the way a naive programmer would expect, you *need* to become experienced and learn the special cases.

    Re: bloatedness. Stroustrup makes the assertion that if you use C++ right, you won't have bloated code. With G++ at least, it is difficult to use STL in *any* way without bloating your code. Perhaps this is a shortcoming of g++ rather than C++. However, I think that the design of C++ makes it difficult for compiler writers to make efficient STL code.

    In some sense, I feel like C++ is like Windows: people use it because they have to, not because they want to. And "have to" doesn't mean it's imposed, sometimes it just means that tools have been developed for it that are unavailable elsewhere. In many languages, I simply can't use yacc, makedepend, the Unix API, etc, etc.

  • by 348 ( 124012 ) on Friday February 25, 2000 @09:05AM (#1246262) Homepage
    Honestly, not many. What we learned (the hard way) was that C developers that were good, were also good in adapting/learning/etc. C++. On the other hand, we did get out of the training business by trying to port C developers to C++. The expectations I had were quite misguided. I understood C++ to be just the next version of C, for the longest time I just never got it that C++ was different. When we did, we looked for C++ developers and stopped the pain, and increased the quality of our code overall.
  • by joss ( 1346 ) on Friday February 25, 2000 @09:15AM (#1246263) Homepage
    Each to his own.

    This is a list of reasons why I personally hate Java. They're not all rational, but hatred seldom is...
    Three points I would like to make up front.
    1. I *know* Java is the best choice for certain things.
    2. Please don't bother telling me all the drawbacks of C++ in reply.
    Believe me, I am aware of many glaring flaws with C++,
    it's just that I've learned to live with these flaws. If I had
    learned java before C++ I'm sure I would find those flaws less
    tolerable.
    3. I'm not a Java newbie. I learned it 5 years ago, and I used it
    nearly full time commercially for the last 2 years, (recently returned
    to C++ with a huge sigh of relief)

    Firstly, the IRRATIONAL REASONS (that I'm aware of):

    It took me years to learn all the pitfalls in C++, and then some
    bastard comes out with a lanaguage in which many of those pitfalls are
    removed. This makes that time more likely to have been wasted and
    makes my skills less valuable. Don't bother telling me that this
    mentality is selfish, stupid and short-sited, I'm well aware of this.
    ------------------------------------------------ ------------------

    I've gotten burnt too many times with Java to trust anything I'm told
    without trying it myself (eg - bug fixed, performance improved,
    memory leaks). I started learning about Java as soon as it came out,
    before books were available etc. I was terribly excited by the chance
    of something to break MS hedgemony, so I was initially enthusiastic.
    That enthusiasm has worn off, and then some, which is why
    I now sound so bitter about the whole thing.

    Java 1.0 was God awful, and the time spent learning how to overcome
    it's shortcomings was a total waste of time. Other equally important
    libraries have changed so much to require any old (2years+) java code
    to need total rewriting. Yeah, yeah, I know, what do you expect with
    bleeding edge technology, but it was managed badly, and Sun flat
    lied about these issues from the beginning.

    ------------------------------------------------ ------------------
    I don't like the default style of the code:

    public ZipEntry getNextEntry() throws IOException {
    if (entry != null) {
    closeEntry();
    }
    ... }

    I prefer matched brackets, (the extra lines are worth the additional
    clarity methinks) and I prefer this_style to thisStyle as a purely
    arbitrary preference.

    public ZipEntry get_next_entry() throws IOException
    {
    if (entry != null)
    {
    close_entry();
    }
    ...
    }

    ------------------------------------------------ ------------------
    Sun's behaviour with Java

    has been pretty disgusting at times. For instance they delayed
    providing a Linux version of the JDK for as long as possible. They
    spread vast amounts of disinformation and pro Java FUD. They made
    thousands of misleading statements wrt performance and stability and
    seem to have effectively brainwashed a whole generation of students as
    to the benefits of Java compared to other languages. The number
    of clueless little student wankers I've heard regurgitating Sun's
    propoganda...

    For some reason people give more credence to what Sun says about
    Java compared to other langauges than they give to what Microsoft
    says about Windows compared to other OS'es, but the same level
    of objectivity and accuracy has been used.

    Sun has done plenty of other boneheaded things with Java, but the
    misinformation thing is the one that irritates me most.

    The other obvious mistake is that Sun never tried to use
    Java to obtain a level playing field. It wanted to keep control
    and replace MS. If they had completely opened up Java initially then it
    would be a different story by now.

    Java isn't a bad language, but it's not "all that" either. IMO ML and
    Eiffel are preferable aesthetically while C/C++ is preferable for
    practical engineering today. I think Java is an excellent training
    langauge, an OO equivalent of Pascal.

    ------------------------------------------------ ------------------
    Exceptions

    I can understand the motivation for declaring the exceptions thrown
    in method declarations, but I'm not convinced it's a good idea.
    The whole point of exceptions is to localize the pain of
    dealing with weird occurences rather than pass the pain up the
    call stack in the form of checking return values everywhere.

    With java, you constantly have to work your way up the call stack
    adding extra exception declarations to methods. It's very
    tempting to either not bother throwing the exception or just
    trap it inappropriately rather than editing half a dozen
    files up the call stack. It's almost as much work as the old C paradigm of
    checking return values everywhere.

    This argument is kinda weak, I know you don't need to declare Error
    exceptions in method declarations, and in some ways it's a good
    thing that it makes you think about the fact that an exception
    could be thrown, I guess it depends on what you're used to.
    ------------------------------------------------ ------------------
    ------------------------------------------------ ------------------
    RATIONAL REASONS for disliking Java.
    (I mean reasons that I don't already know are irrational)
    ------------------------------------------------ ------------------
    Java is slow.

    I don't care how many benchmarks Sun comes out with
    claiming the latest JIT has "C++ level performance". It's just not
    fucking true. While we're on that subject, these benchmarks always
    show considerable difference between C++ and C level performance. You
    only see a significant difference in performance between C and C++ for
    a given task if either (a) the C++ programmer didn't care about
    performance or (b) the C++ programmer was stupid, in which case all
    bets are off. You can write hand crafted assembly that's slower than
    Java if you're stupid enough.

    A uncontrived comparison is at http://sprout.stanford.edu/uli/java_cpp.html
    In summary, with HotSpot 1.3 beta, (a JIT that Sun touted as being
    faster than C++ !!) Java was roughly 5 times slower than C++.

    The performance hit from Java comes more from it's crappy libraries
    (Swing anybody) than the JIT aspects. Bounds checking, garbage
    collection, and inherent overhead of OO techniques all cause a
    performance hit, but the real trouble comes from crappy libraries
    that put 10 levels of indirection between a request and it's
    implementation.

    For instance the String class being written with 16 bit characters to
    make it unicode friendly when 98% of the java code written never uses
    this feature but it still requires twice the time and space for every
    operation. Also Strings are not alterable so to alter a character you
    create a new StringBuffer object, copy everything, make an adjustment,
    then replace the old reference with the new so the old object
    eventually gets passed to garbage collection... all compared to
    buf[i]= 'a'; (C or C++). It's crap like this that really makes Java seem
    so slow, not the JIT hit.

    Basically Java is slow for the same reason that Windows sys admin is
    slower than Linux sys admin. You don't trust the user with the rm
    command or trust the programmer with pointers - show him an idiot box
    if he tries to delete a file or bounds check that array access for
    him. It's one way of doing things, but it sure isn't efficient.

    ------------------------------------------------ ------------------
    Missing language features (compared to C++)

    * templates
    No, just because everything is derived from Object, does
    not mean you don't need them. Writing container classes for Object is
    equivalent to writing container classes for void * in C++. You can do
    it, but it's not ideal. Besides templates are useful for more than
    just container classes. See http://oonumerics.org/blitz/ for an
    advanced example.

    * enum
    Java is meant to have stricter type checking than C++. It seems like
    the kinds of mistakes an experienced engineer
    hardly ever makes are guarded against, but the kinds of mistakes
    that people are likely to make are more likely in Java because of
    the lack of enums or templates. The only reason for their absence
    is the added complication - that only makes sense in a training language.

    * multiple inheritance
    Interfaces are pretty good, but MI is more powerful and abstract virtual
    inheritance if equivalent to interface, so interfaces are subset of MI.

    * preprocessor
    "not needed because Java is platform independent" -
    hahaha. No it fucking isn't, but a more common need for the
    preprocessor would be to ease the pain of version changes. You either
    end up with duplicated code bases or you hack your own preprocessor on
    to javac, or you deal with a minor headache for every minor version
    change or a huge headache for major version changes (1.1 -> 1.2 or 2.0
    as it's now called).

    * operator overloading
    String str = (String)vec.elementAt(i);
    versus
    string str = vec[i];

    It's even more striking if you're working with matrices and vectors
    etc, but I've thankfully managed to avoid the pain of doing that in
    java.

    Now we get into the "these language features can be abused" argument.
    It's easy to show examples of the dangers of misusing MI or operators.
    I think this is pure packer mentality. You cannot make programming
    idiot proof and it's a mistake to try. This mentality pervades java
    and is probably the single thing that really makes me hate it. The
    notion that you prevent everyone from doing something because
    "some people abuse it" drives me crazy.
    ------------------------------------------------ ------------------
    Verbosity

    Java code just tends to be longer than the equivalent in C, C++, perl
    or ML (unless of course you're implementing something that is nicely
    covered in the libaries)

    There are several reasons for this.

    Insistence on using OO paradigm all the time.
    Missing language features (especially operator overloading)
    choice: boolean Concept.Conventions.StyleGuide.LongFunctionNamesDe sirable() { returns true; }

    This relates to something I've never fully understood. Several people
    who's opinion I respect insist that they can develop stuff faster
    with Java than with C++. If they really know C++ I just
    don't understand this, unless they are comparing old
    (pre-STL) C++ with modern (post-collections)java.
    The other possibility is that they have been using MFC, a
    piece of code so vile, that I can barely speak it's name.

    I can see that if you're working on a project where (2 or more apply):
    threads are important;
    has to work on multiple platforms;
    requires functionality that JDK library classes cover well;
    is deployed over the internet;
    speed is not an issue;
    memory useage is not an issue;
    very precise control is not important;
    some team members are inexperienced;

    then Java may well be the best choice.

    However for implementing arbitrary fresh functionality I can develop
    far faster in C++ than java. For instance a fragment of a C++ program
    that reads in a file and gets a list of the starting positions for
    every word in the file:

    map > word_positions;
    string word;
    while (cin)
    {
    cin >> word;
    word_positions[word].push_back((int)cin.tellg() - word.size());
    }

    Writing the equivalent in Java would take 20+ lines.

    Now, I admit this is a contrived example, but do it the other
    way round - give me a nice piece of algorithmic code in Java,
    that is not dependent on some database/graphics/network library
    and I believe the equivalent C++ will almost always be smaller.

    ------------------------------------------------ ------------------

    Libraries

    I don't like the JDK libraries much. This is mostly a maturity
    issue, but also it's a kind of OO at all costs mentality.
    For instance using NumberFormat & PrintWriter to create
    precisely formatted scientific output is immensly painful
    compared to using printf() (iostream's suck for this too).

    "simple stuff should be easy and difficult stuff should be possible"
    Java libraries lose points on the first half, but are generally OK
    on second.

    Using stuff like Dictionary is unpleasant compared to STL
    - there's no way to avoid this due to the lack of templates
    (BTW I am aware of Pizza, and this is definitely a step in
    the right direction, but unless Sun adopts Pizza it's
    not really worth bothering with).

    I started on my last project before I knew about FLTK, and
    portability was an issue which was why I chose Java for the
    interface part of the project. Swing has quite a good design,
    but a shitty implementation. It's buggy as fuck, and seriously
    inefficient. Learning how to work around it's shortcomings is a
    right royal pain in the ass. It has gradually improved, but
    is still slow, leaky, bloated, buggy, and perverse in places.
    Stick a breakpoint in at any point in the code - the callstack
    will be at least 15 levels deep. It's still preferable to MFC
    though, which has shitty implementation coupled with *appalling*
    design.

    Swing is wonderful compared to AWT, but I wish they
    had worked harder on stability and performance and less
    on features. Visual Basic based applications feel much
    faster than Swing even with the latest JIT.

    ------------------------------------------------ ------------------
    Printing
    Why did they hardcode the output to 72dpi ???
    It's just typical Java. You get the performance of 5 years
    ago on the latest hardware. Not a good use of Moore's law IMO.
    (There is a workaround to this using drawImage() but that has serious
    problems too...)
    ------------------------------------------------ ------------------
    Tools

    javac versus egcs/make,
    gdb v jdb,
    VisualC++ v. Jbuilder3
    DDD v ...er... DDD
    purify v JProbe
    quantify v JProbe

    The C++ tools just have a greater polish.

    This is an unfair comparison, since it's not really Java's fault
    and is just a matter of time.
    (Actually, the problems with JBuilder3 *are* java's fault.
    JBuilder3 is mostly written in Java and it shows. It's virtually unusable
    with less than 128Meg of RAM, 256M is recommended.)

    ------------------------------------------------ ------------------

    And that's enough ranting for today...
  • by raph ( 3148 ) on Friday February 25, 2000 @08:26AM (#1246264) Homepage
    Bjarne mentions the poor education of C++ programmers frequently in this interview. I can't help but think, is this poor education a direct result of the complexity of the language?

    I think that it's a much shorter learning curve to learn the C language fairly well than C++. I think this has helped in the Gnome project, although I'm sure there are people who feel differently.

    That said, many of the historical reasons for disliking C++ are becoming obsolete. In particular, the language seems to be settling down standards-wise, and there are now decent implementation to be had, both free and non. I've only used C++ sparingly in my own work so far, but I look forward to expanding my use of the language.
  • by hanwen ( 8589 ) on Friday February 25, 2000 @09:25AM (#1246265) Homepage Journal
    Thanks for answering my question.

    Now that I am reading your replies (and of course after reading your
    FAQ as well), I've started to notice that your replies center on the fact that

    C++ is better than C


    Or maybe even the less subjective


    Complicated programs in look better in C++ than in C


    This is patently true, of course. C++ has support for various nifty
    features that make a large C project more easy to manage. In fact it
    describes precisely what I felt when I traded C++ for C: no more
    hassling with function pointer tables was needed. I could simply use
    a virtual function, great!

    My problem is "better than C" is no longer good enough for me.

    I've grown a lot in my programming skills, and my projects have grown
    with me. A little detour: my pet project is GNU LilyPond, a music
    typesetter (free software of course) written and maintained largely by
    myself: it consists of about 55000 lines of C++.

    The problem with this application is that

    1. music typesetting is _very_ complicated

    2. every formatting detail should be tweakable.

    Since I've started it almost 4 years ago, I've learned a lot, and also
    came in touch with languages like Python, Haskell and LISP. Half a
    year ago we made the step of converting large portions of the C++ side
    to GUILE (the embedded Scheme interpreter of the GNU project).

    This step has dramatically simplified most of the code in LilyPond:
    now we have garbage collection, generic types without the overhead
    templates!, a clean way for users to plug into this system using
    Scheme, etc. (if you want details of what kind of uglyness went away,
    tell me, I can explain). This revelation caused to me reconsider C++
    as the ultimate language.

    In python, I can simply write

    for x in func1, func2:
    [some complicated code with x]

    in C++, I'd have to go through the hassle of defining the correct
    function signature as a typedef, then build an array, and then loop
    through that array using an integer, eg.

    typedef void (*fptr)();
    ..
    fptr[2] = {&func1,&func2}
    for (int i=0; i

    And usually, I don't go through the hassle , and just copy and paste
    [something complicated], which is also a Bad Thing. Maybe this is a
    slightly contrived example (I'm not sure about the typedef), but
    learning Python and LISP has made writing C++ a generally painful
    experience for me.

    Maybe nowadays some of my gripes may be soothed by the Standard
    Libraries, but I don't feel like learning yet another big C++
    component, all the more because I know that afterwards C++ will still
    not be good enough (or will it ever have reflection, higher order
    functions, GC?)

    In this light, I find your statement that

    starting to learn C++ is easier than starting to learn C

    dangerous, as are the examples in your "learning C++ as a new language
    paper" for they imply that any of these two languages can or should be
    a "first" language.

    Do you really want people grow up with a language that has distinction
    between non-immediate objects on the heap and stack, no automatic garbage
    collection, pointers, no initialization, no higher-order anything?

    You're educating people about C++: fighting misconception, telling
    them where it is good for. But you're not telling them what it is bad
    for. C++ is immensely popular, and people easily get the misconception
    that this popularity makes it a good language start programming with,
    or to write their highly tweakable programs, etc.

  • by brad.hill ( 21936 ) on Friday February 25, 2000 @09:26AM (#1246266)
    Of course, the Be people are by no means "old dogs". There is nothing legacy about BeOS.

    On the other hand, IBM (the oldest dog in the book, but with more new tricks than anybody) entirely rewrote AS/400 in C++. They claim it was the largest OO project ever undertaken and was a spectacular success. Also, it seems that having an OO architecure at the core of the OS allosed them recently to integrate a JVM into the AS/400 kernel that's amazingly fast and scalable.

    I actually find it strange that C++ is thought of as unsuitable for systems programming. To me it seems exactly suited for that, while Eiffel or Java are much more suited to business programming.

    Perhaps the argument is more fundamentally that OOP is unsuitable for systems level development, which the above example blows to bits, of course.

  • by DaveHowe ( 51510 ) on Friday February 25, 2000 @08:35AM (#1246267)
    Bjarne mentions the poor education of C++ programmers frequently in this interview. I can't help but think, is this poor education a direct result of the complexity of the language?
    More likely the fact that C++ tends to be taught by lecturers more familiar with C. I suspect better training for lecturers would result in better training for students :+)

    I think that it's a much shorter learning curve to learn the C language fairly well than C++. I think this has helped in the Gnome project, although I'm sure there are people who feel differently.
    I suspect a lot depends on what you have learned before it - I found C easy to learn having already studied Basic, Cobol and Pascal - all procedural languages. Had I went from a base of OO language to C++, I would probably have regarded the C subset as a primitive reminant suitable only for things not worth wasting the full glory of objects on.....

    That said, many of the historical reasons for disliking C++ are becoming obsolete. In particular, the language seems to be settling down standards-wise, and there are now decent implementations to be had, both free and non. I've only used C++ sparingly in my own work so far, but I look forward to expanding my use of the language.
    I am being dragged kicking and screaming into C++ :+)
    well, I might not be THAT badly off, but the Microsoft Visual C++ compilers seem to go out of their way to make using classic C awkward, so I am having to adopt C++ in self defence.
    --

The end of labor is to gain leisure.

Working...