C++ Answers From Bjarne Stroustrup
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.
- 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.
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.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.Derivation also allows for partial specification of template arguments in the definition of a new type: template class X { /* ... */ };
template class XX : public X { };
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.
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.
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.
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
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...
Well I think C++ could have been better with bundled standard libraries.
According to the documentation, one usage of this is to implement "memory-sensitive caches".
See the java.ref package for more details.
Sebastian
Guh. I actually worked on that many years ago (not the lower level but the programming API - MessageHandler to be specific). In any event, I don't know which "hardware interface" he is talking about but I'm pretty sure the lowest level was a glom of C and ASM. There were a couple hardware emulation and abstraction layers that sat real close to the iron that were written in C++ though. What was _great_ was the developement environment- They had an IDE called LanDE which ran on the RS6000s and AIX. I loved it.
:)
Of course, this had to be 8 years ago, and I can't remember what I ate for dinner last week, so its worth what you paid for it.
Pax -- Ob
A whole lot of good points in joss' post. I was very happy to see joss recommend my own indentation style, which I am very religious about.
I also especially liked joss' comments on the heavy cost of Java's immutable String class. It is disgustingly expensive to do a lot of string-type operations in Java because you have to create a new String object every time you work with a frequently changing string. They tried to make StringBuffer work efficiently with the String class.. if you extract a String from a StringBuffer, it actually re-uses the char[] array from the StringBuffer, so the overhead there is lower than you might think, but if you then try to re-use that same StringBuffer (by setting the StringBuffer size to zero and then adding new chars into it), StringBuffer behaves very poorly. It actually copies the char buffer from the old String at its full size before zero'ing it out, so if you ever extract a large String from a StringBuffer, you can get some very bad memory usage if you try to continue working with that StringBuffer thereafter.
I really love Java, and I've been working with it almost exclusively for the last four years, but there are many things like this that are only slowly being fixed. The right way to think about Java is as an operating system, with all of the complexity that that implies. You wouldn't expect a four year old operating system with all of the features that Java supports these days to be terribly mature, and Java still has a way to go.
For all of that, I do love Java, because it does work surprisingly well, all in all. My project (see my .sig) couldn't have been done with the resources we had to devote to it using anything else, and Java's precision, exception support, threading, API collection, and garbage collection make it possible to do very ambitious things with it.
- jon
Ganymede, a GPL'ed metadirectory for UNIX
I have the dubious distinction of being an experienced coder for both MFC and for the bare Windows API sans MFC. Rather than saying MFC "doesn't abstract that functionality very well", it would be more accurate to say it "doesn't abstract that functionaily very much". MFC is a rather thin wrapper around the Windows API. Frankly, it doesn't really abstract away from it at all. It just adds some nice wrappers so you can use it using OO syntax.
--
"Convictions are more dangerous enemies of truth than lies."
They say it's only a game...
...they lie!
--
"Convictions are more dangerous enemies of truth than lies."
Funny, I always trust people more when their motivations are obvious, when they make no effort to hide them. Ted Kopple(sp?) made a similar point recently when asked about Sam Donaldson, who tends to be very open with what his own opinions are on some shows (e.g. This Week). The questioner seemed to think this made it harder to trust Sam's reporting on issues when you knew what his bias was. Ted pointed out that, like everyone else, Ted has his own biases. Are you better off trusting a new report by Ted, who keeps his biases hidden from view? Seems to me its easier to evaluate the story presented by Sam, since you know what his bias is and can take it into account, than it is to evaluate the story by Ted. By not airing his own views, Ted presents the illusion of being unbiased, but in answer to this questioner, his openly pointed out that this is a complete illusion, he does have his biases, same as any other reporter.
In short, it's a lot easier to trust someone when their motivations are plain, open, and blatant. Only a fool trusts people more when they know their motivations less...
--
"Convictions are more dangerous enemies of truth than lies."
Strong-typing gets you wonderful compiler performance. It should be used for anything where performance is essential. This does not negate the fact that it is hideously evil and should be avoided whenever possible, unless you like clunky, inelegant code...
--
"Convictions are more dangerous enemies of truth than lies."
--
"Convictions are more dangerous enemies of truth than lies."
You don't. Just like you don't need a compiler to write computer programs -- entering raw hex into a file works just fine if you're good enough at hand assembling your own code and understand the executable file format. But just because you don't need something doesn't mean it's not useful to have.
COMPUTERS ARE NOT OBJECT-ORIENTED; NEITHER SHOULD PROGRAMMING LANGUAGES BE.
Extending this argument to its logical conclusion, programming languages should not have structs, since computers only deal with information a register at a time. Why create this completely unnecessary higher level abstraction when it doesn't allow you to do anything you couldn't do before? Also, things like for and while loops ought to be replaced by labels and conditional gotos.
Perhaps because it makes life easier in many cases?
But in the name of progress, everyone wants of course to adopt a language that actually lets them do LESS
You mean like C? What's with these "functions" in C? C has this silly concept of a block of code that can ONLY be entered at this ONE point, so you can do LESS with it than if it allowed entry at any point like you can in assembly. What's with that? Why is C so limiting? Why can't I include in a function call a label within the function to start execution at?
Perhaps because it's dangerous and unnecessary?
The point being, C does all the same evil things you complain about C++ doing. It introduces unnecessary abstractions. It limits you, preventing you from doing things you "ought" to be able to do (if you think that because the CPU will let you do it, you "ought" to be able to do it). This is the price you pay for not coding in assembly language. Live with it, or don't, but it's silly to complain that the problem with such and such a language is that (to interpret your words down to their base meaning) it's not assembly language.
--
"Convictions are more dangerous enemies of truth than lies."
Actually, there's usually no risk at all of a Class-mismatch -- I know nothing has been put into the container other than Thingamabobs. What bothers me is, I know that what's coming out is a Thingamabob, and thus a run-time type check here is not necessary, but there's no way for me to tell the compiler that.
Not only is this ugly, you also loose all advantage of a strongly typed language.
You can avoid the ugliness by creating a specialized container (e.g. make a class ThingamabobContainer). This also means you don't need to typecast what comes out. Unfortunately, this doesn't really avoid the typecast, it just hides it (it occurs inside the code for ThingamabobContainer), and adds another level of crud into the code.
This would all look much prettier and be more elegant if Java had simply given in and been the weakly-typed language it should have been. Of course, this is the opinion of a warped Lisp fan...
--
"Convictions are more dangerous enemies of truth than lies."
I hearby nominate this for Understatement of the Month!
--
"Convictions are more dangerous enemies of truth than lies."
My company develops FreeBSD-based Internet firewalls and VPN gateway products. All of our coding is done in C++. We get far more code reuse, consistency and robustness as a result. For example, part of our class hierarchy is Process->Server->Proxy->Relayer. With this C++ library for writing servers and proxies, adding new servers or proxies that have consistent authentication methods, log message formats, etc etc, is usually always a trivial exercise (for example, it took only a few hours to implement a POP3 server, most of which was writing the new classes to handle maildrops).
I *love* using C++ for systems programming!
Graham Wheeler Cequrux Technologies Internet Firewalls/VPN Routers/Encryption Software
Does this help?
I was looking for some reference to "I wish I had done that better" or something. Even Gosling has his regrets...
there are 3 kinds of people:
* those who can count
there are 3 kinds of people:
* those who can count
* those who can't
Me thinks someone has been playing too much illuminati.
--locust
I have to say that even with good programmers, most problems arise from human error. This should tell us to write languages and develop tools that conform to human weaknesses rather than make humans jump through hoops for the compiler's sake. I think C++ sacrifices simplicity for performance to a degree that is no longer necessary--especially considering the modern optimizing compilers and cheap hardware we have now.
Personally, I find it much easier to read because of this. Perhaps it's just preference.
C++'s object syntax is definitely more consistent with its C origins.
Hmmm...I wonder if my preference is because I don't think traditional C syntax is very efficient for object oriented concepts.
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.
As I understand things (and I may be wrong), the quality of ObjC compilers has risen to a point where messages are pretty close to regular C function calls. I have at least been told by "people who benchmark this stuff" that ObjC is on par with regular C now.
Part of what made Obj-C so pleasant to use on the NeXTstation was the rich object class library that NeXT developed.
I'll drink to that!
Java's JFC/Swing libs are certainly rich but somewhat strangely organized.
My dad is currently learning Swing and said that the book claims that it's related to NeXTSTEP. Perhaps I'll get the chance to take a look at it soon...
I don't disagree with you; my real issue is what I perceive to be a readability/comprehension problem with C++. I think the syntax and visual arrangement of a language has a huge impact on quality by making it easier (or more difficult) to understand what's going on. Plus, I believe in K.I.S.S.
While I understand your point--and in application to Bjarne Stroustrup, this makes perfect sense and is correct--the mark of good journalists is that you can't tell what their own views are by simply watching their presentation of events.
I know this is off-topic, and I apologize profusely...
Honestly, I much prefer ObjC syntax; I find both C++ and Java confusing and hard to read. Maybe this is just preference, I don't know.
I would say they should learn them at some point during the neophyte stage of developerhood. There are computer engineers and computer science majors just graduating that don't know how memory allocation and memory management work, and they're unaware that their use of language features can have any affect on runtime. I work on a project that develops OS-like things, and we're seeing a barrage of new grads that are confused by having to do their own memory management or pay attention to what language features actually do. There were actually some fairly bright people interviewed recently that had to have pointers explained to them. Regardless of language, not knowing the realities of memory usage/management has serious potential to make you a lousy developer in other languages. Now, that said, I'm not a blanket advocate of non-OOP languages. I think there are many oop language features that ease development and make maintainance easier. I even use some of them in projects I do outside of work (I'm actively learning c++, and I've programmed in smalltalk for a while), it's just that a good chunk of the software development world does work where real-time issues and hardware constraints are an issue. Not knowing how to use a pointer pretty much rules a person out as an embedded developer, compiler-writer, operating system developer, as well as many other things. Hell, even for programming in a language that doesn't explicitly have pointers, and that has garbage collection, I'd still like the person to know how to work with memory. I'd think a java or smalltalk developer that had never used a language that didn't keep track of memory for you would make a pretty lousy developer in their respective language.
Wrong! this isnt about bahavior. Its about abstraction and class
data member integrity. You are confusing the two.
Of course I use encapsulation if invariants must be enforced. That is
besides discussion. What I am talking about is when there is no such
thing as "data member integrity".
Wrong! This is a design issue, not a language
issue. Functionality shared between objects should be abstracted into
a separate object
The part of the program that was the most incestuous with objects is
undergoing this transformation right now, but the "objects" are going
to be scheme functions, because what I want the program to do can't be
expressed in C++ conveniently.
This is NOT OOP!
Maybe you should read, erm, study the following quote by Bjarne
Stroustrup:
OOP wasn't a panacea. [..] [OOP] 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.
This is a red headed stepchild of OOP!
And I happen to like redheads.
Han-Wen Nienhuys -- LilyPond
By your (flawed) logic all 3D renger engines should be written in Python or Scheme!
You are wrong. The topic that we were discussing was a music typesetter
specifically, and definitely not a 3D rendering engine.
C++ is FAR more expressive and extendible than [Scheme]
I rest my case. You have no clue.
Han-Wen Nienhuys -- LilyPond
I stand corrected. For looping over functions with one argument, you need only one template. Then you want to loop over functions with two arguments. Another template. Then you want to loop over member functions. Another template.
/*
Catch my drift?
And this is only folding repetitive code into small loops. There is lots more that is obtuse in C++ for no good reason.
Why the hell are you constructing a new list every time you need to iterate over an existing list?
I am iterating over lists to fold repetitive code into loops. The contents might have been passed as
arguments to a function, example below. I am not iterating over an existing list in the first place.
You're still missing the point:
1. C++ adds lots of overhead that is just preventable. This is the part that makes C++ generally painful
2. C++ lacks some features because it is still
C with OO bolted on top. This makes C++ impossible for some projects.
real-life code sample follows (sorry for the lousy formatting). Notice that the two member variables (names ending in underscore) are not stored in lists.
void
Score_engraver::set_columns (Paper_column *new_command_l,
Paper_column *new_musical_l)
{
Paper_column * news[] = {new_command_l, new_musical_l};
Paper_column **current[] = {&command_column_l_, &musical_column_l_};
for (int i=00; i != 2; i++)
{
if (*current[i])
{
if ((*current[i])->linked_b())
{
pscore_p_->add_column((*current[i]));
scoreline_l_->add_column((*current[i]));
}
else
{
We're forgetting about this column. Dump it, and make SCM
forget it.
(UGH.) */
scm_unprotect_object ((*current[i])->self_scm_);
*current[i] =0;
}
}
if (news[i])
*current[i] = news[i];
}
}
Han-Wen Nienhuys -- LilyPond
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?
The client, that's me as well. I am perfectly aware which parts of the
interface are considered public which are not. I am a consenting adult
(wink).
One thing that bothers me about C++ protection zealotism
(encapsulation, if you will) is that it assumes that behavior is
something that can be encapsulated within one class. In the program
you are referring to, a large part of the behavior emerges because two
objects have "shared" behavior. Putting private: everywhere
constrains the code, because it forces particular code to be in a
particular class. The result is that half of the code is in a class
where it belongs, and the other half is not. Moving the variable to a
different class merely switches the halves. (The last chapter of SICP
has an interesting footnote about this as well).
In any case, my default mode is prototyping, and making everything
public. The moment that a reason for encapsulation emerges, I make the
relevant variables private, and the compiler catches all encapsulation
violations for me. These are usually trivially to upgrade to a new
interface.
I'd suggest you study TC++PL
In fact, I've read it cover to cover. I learned C++ from it.
Han-Wen Nienhuys -- LilyPond
Hey,
.. you never
thanks for listening to me
(assuming you're the same guy
know with these AC comments.)
Han-Wen Nienhuys -- LilyPond
Some things may be prohibitvely hard to do [..] but they are
still possible with C++
So what are you trying to say? That they're turing complete? Not a
very useful observation.
[on the fly code generation and execution] This is one area where
scheme would obviously be more efficient, but it doesnt sound like
those are the types of algorithms we are talking about
Actually, the case I had in mind involved scanning all pointer members
of all objects deriving from a specific class. In C++ this is very
painful, because you don't have reflection. We moved all variables
(including C++ pointers) into an association list, and recursively
scanning that list is very easy, because you do something like
Scheme
scan (Scheme s)
{
if (ispointer (s))
{
[do_something and prehaps return
UNDEFINED]
}
else if (ispair (s))
{
Scheme a = scan (car (s));
if (a == UNDEFINED)
return scan (cdr (s));
else
return cons (a, scan (cdr (s)));
}
return s;
}
(The crux is that you filter all pointers that end up as UNDEFINED,
from lists in the variable association list. The C++ version had to
take out the pointers of arrays in derived classes one by one which
led to quadratic behavior.)
I'll admit you can do this in C++, but I don't think you can do it
without duplicating a substantial part of a Scheme data structures.
Han-Wen Nienhuys -- LilyPond
I picked a random file, translator-group.hh.
You managed to randomly pick one of the two most complicated files
(the other being score-element.hh).
Virtual inheritance [..] You have a destructor and copy
constructor, but no assignment operator. That likely means serious
problems if someone tries to assign to an instance of this class.
And you know C++?
A class that has a virtual base class is part of hierarchy and usually
accessed through a pointer to the baseclass. Assigning instances would
lead to object slicing, which is why it has a copy-constructor and
clone() function.
(So sue me, I didn't add a private operator=() )
Han-Wen Nienhuys -- LilyPond
Also, sooner or later, you're going to run into speed problems in
a music type-setting program. Some speed cost is
inherent in the fact that your language isn't strongly typed
It's very well documented that you get more speed increase from better
algorithms than from small optimizations (such as eliminating type
checks).
In a more expressive language (like Python or Scheme), you have more
ways to write code, so you get more chances to use better algorithms;
this is in fact something that happened when we used the Scheme
interpreter in LilyPond.
And your point about the cost of type checking isn't clear-cut as it
seems. For genericity in C++, you need templates . Templates have a
tendency lead to larger object code (well, in my experience anyway.),
which in turn have lousy cache behavior.
Han-Wen Nienhuys -- LilyPond
it's perfectly trivial to write a single function template
And that is precisely my point: a function template takes up 5 lines of code, and using it another 2 (constructing the list, iterating). Contrast that with the one line python.
that's a sevenfold increase in code size.
Multiply the amount that you do loops over two element lists in a 50000 line program.
That's a lot of preventable complexity.
Han-Wen Nienhuys -- LilyPond
Thanks for giving me another way to reduce code, maybe I'll add a bit
of it. However, I am not sure if passing member functions that set
member variables which are passed as arguments count as "elegant" in my book.
Han-Wen Nienhuys -- LilyPond
Some comments from a semi-enthusiastic Java programmer:
:-)
I don't understand why people complain that Java
is too object-oriented. If you don't need objects, use a class where every method is static. Such a class is the equivalent to a non-objected-oriented module or namespace. (I will agree that the Java class libraries are missing some important static convenience methods, particularly when it comes to formatting numbers, but you can write your own until Sun wises up.)
As far as polymophism (templates) goes, I can't remember the last time someone here screwed up by storing the wrong type in a container. Eliminating the cast when fetching from a container would be cleaner syntax but it doesn't catch a whole lot of errors in practice. (Perhaps this is because I mostly use Vectors and Hashtables as instance and local variables and rarely in method parameters or return values.)
I agree that you should not trust anyone's promises with respect to Java's performance or bugs, especially Sun. Do your own tests. Pick a set of VM's to support (wich exact version numbers) and add to it cautiously. (Just because 1.2.1_03a works, do not assume 1.2.1_04 works.) Never promise "run anywhere".
I'll agree that enum would be nice, though I don't use constant integers all that much.
Re: datatypes. As a former Perl programmer, I'm convinced that the three essential data types are string, extendable array (a.k.a. Vector), and hashtable. If you have efficient implementations of all three with convenient syntax, you can build anything else easily. Java doesn't measure up, particularly with its slow String and unextendable array types, but at least it has standard (though inefficient) String, Vector, and Hashtable classes (and the 1.2 containers will be helpful). Contrast this with the zillion string implementations in the C/C++ world.
I think Java's going to win for a while, based not on the language so much as standard threads and the ever-expanding enormous standard library. Who even needs to write algorithms anymore when you're handed them all? (Just kidding
re: Swing. Luckily I've never used it since I don't do client side. Maybe 1.3 will be tolerable.
#include <stdio.h>
int main(void)
{
printf("Hello, World!\n");
}
Don't you really mean something like this?
#include <cstdio>
int main()
{
printf("Hello World!\n");
return 0;
}
DFL
Never send a human to do a machine's job.
In my defense, though, g++ doesn't handle them right yet either. So std::printf("Blah\n"); and printf("Blah\n"); are effectively equivalent.
Actually, I also mistook your point. I thought your point was that the equivalent C++ program was exactly the same length as the C version.
Sigh. Some days it doesn't pay to nitpick...
DFL
Never send a human to do a machine's job.
This was a great article. Probably the most information I've seen in one article on Slashdot. Thanks to Bjarne for answering the questions with such eloquence and humility. And thanks to the moderators for picking some really great questions. Though, I am surprised that there were no questions asking about the future of Java? Were there not any good ones? Or was there an intent to keep the questions focused on C++?
What are you doing writing a GUI in C++? You are a BAD MAN! Heh!
Just kidding. I would like to suggest that C++ is not the best language to write a GUI in. In fact, if you've got a large software project, it's not likely that a single language can possibly be flexible enough to easily cover all the pieces well. Maybe it is better to write pieces that C++ works well for in C++, but make it interoperable with a better language for building GUI's. I'm not suggesting that Tcl is a great language for GUI's, but it's fairly easy to embed a Tcl interpreter into a C++ program and use Tcl for some quick and dirty GUI work.
So maybe the lack of really good support for a standard GUI library is a good thing. You have choices and alternatives. You are not forced to implement using the MSFoundation Classes just because that's what everyone else is using.
If tits were wings it'd be flying around.
You can try ddd. It's a really nice shell on top of gdb.
If tits were wings it'd be flying around.
It takes brains that think on many levels to write good C++ code.
Those brains dont congeal in hard skulls very often.
That is the problem. Most of the developers out there that DO write bad code could read until they are blue in the face and STILL not *get it*. I read X number of books on Y. I know what im doing!
This is EXACTLY the type of mentality that is a SCOURGE! yes, a SCOURGE! i cannot bash this type or arogant, self righteous ignorance enough. WAKE UP!! It is YOUR skills at risk, YOUR code that is affected. It is entirely worth your while to drop the expert fascade and think about everything your doing as if it may be wrong. Guess what, everytime you find something that can be implemented or organized in a better / more efficient manner. You may not be flat wrong most fo the time, but there is ALWAYS room for improvement.
Allright, my patience is tested...
What I am talking about is when there is no such thing as "data member integrity".
This is in the land of BAD CODE. Period.
The part of the program that was the most incestuous with objects is undergoing this transformation right now, but the "objects" are going to be scheme functions, because what I want the program to do can't be expressed in C++ conveniently.
At least you admit it was bad design. Scheme may very well be a great choice for the implementation of that piece of code, that wasnt my point though. It is the FACT that public data members are not only BAD, they are VERY BAD, and violate the msot basic concepts of OOP or even good coding practice in general.
Maybe you should read, erm, study the following quote by Bjarne Stroustrup:
OOP wasn't a panacea. [..] [OOP] 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.
Correct. So use SOMETHING ELSE, but dont try and use a bastardized class. That is WRONG. Im sorry if youve convinced yourself otherwise, by thinking, wow, for 3 hours I thought about this and I cant think of a better way. There must not be one so lets break some fundamental guidlines.
I will repeat. This is a DESIGN ISSUE! Just because you dont understand C++ and the design required for that peice of the code doesnt mean you are right, and can violate all sorts of common practice without thought of correction or pending consequence. This kind of code is crap. Pure crap. Sorry, but I dont think any other means of explaining it will get the point across.
And you refuse to accept responsiblity for the development process. At least if you continue to assert the fact that all the problems you mentioned COULD NOT HAVE BEEN PREVENTED with reviews, testing, and standard process.
;)
I think your an offended VB Scripter that wishes he was coding linux candy...
10,000 monkeys with typewriters can write C++ code! so what?!?!
Some people have been coding for years and write shit code. It shouldnt be a surprise. Because they never learn and continually refine their skills as they go.
But there are also people who have only been coding for months that can write some very good C++. Its not about time frame, its about the developers commitment to self improvement, value and refinement of skills, and motivation. (lastly, mental capacity, but even this doesnt have much effect without the previous attirbutes)
In this case I AM blaming the above gripes on the programmer. The deisng of this individuals application is horrid, and hes passing off judgment on the language because of it. All of the issues I have seen him make so far with respect to C++ being a poor choice in light of Scheme or Python are due to implementation and design issues. And he obvously discounts these right off, as he knows what hes doing and how to utlize the powerful features of C++. That is the part thats pissing me off, and that is the part that I am criticizing...
I just read Ian Joyners document. It can be summed up in one point.
C++ allows you to do bad things (if you dont know what your doing), and various other gripes about cosmetic details.
Whether this is bad or good is entirely subjective. There are cases where the 'dangerous' features mentioned are actually quite handy, and aid the deisgn of a given implementation. All of the pitfalls that Ian mentions are avoided by good programmers. The author is just biased towards a more rigid OO implementation such as Eifel or Java.
Ahaha.. I eschew Charlie Moore!
Abstraction is not only nescessary, it is VITAL. And always will be. It is your tool of comprehension in the face of massive and nested / recursive complexity and chaos!
Anyone who says otherwise is a blind fool who is calling abstraction by another name.
Its a trade off.
And good programmers dont write bad code. You can write a half million line code system in C++ and not have any memory leaks or pointer errors. It is possible, and in good programming teams, with reviews and standards, this is a minor issue. These errors are programmers faults, not language faults. They arise because of the POWER of the language. Sure you can use a less powerfull Java implementation, and it may be well suited for the development task at hand. But there is always a trade off. It will be slower, fatter, and have less features available to the coders.
Its a design decision in the end, and personally I think more time should be spent making better coders, than writing more abstracted, fatter, less powerfull tools.
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.
Hes not an idiot in the knowledge sense, but an idiot for refusing to accept the fact that he does NOT understand C++, and does not know how to write good code. The evidence is right there, written with his own hand, but until this individual realizes that his code has much room for improvement, it never will! This says nothing about the complexity of C++ in and of itself, other than the fact that some people consider themselves very skilled C++ coders because they managed to cludge together a pile of crap that doesnt drop core.
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.
I think the average person doesnt want to invest the effort into refining and honing their skills. Perhaps the mindset of the lillypond guy is indicative of the average C++ coder which would certainly explain why, after many years and lots of code, they STILL cant write C++ code that is worth the bytes its stored on.
So what are you trying to say? That they're turing complete? Not a very useful observation.
You said CANT be done in C++ but CAN be done and done fast and easy with Scheme. That was the bullshit I was stomping on.
Actually, the case I had in mind involved scanning all pointer members of all objects deriving from a specific class. In C++ this is very painful, because you don't have reflection.
Sorry, I cannot think of anything even remotely relevant where this would be nescessary. And EVEN if it were, a member method overidden by each derived class should handle this type of functionality. Again, this is a design issue, and as stated multiple times before, your design is horrible, and its causing all sorts of problems down the line.
n 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..
What are you trying to say? That C++ applications cant use thrid party libraries? Oh wait, your only saying that you dont have to relink. Well, that little convienance comes at a price. Namely big fat binaries with lots of added overhead.
The reason STL is so nice is because it IS a language standard, and is wonderfully extensible and usable.
OOP Resuse is VERY alive in C++. Your an ignorant fool if you are suggesting otherwise. And its the very generic features of C++ (templates, multiple inheritance) that provide this ability to reuse code. Your only point has to do with cross platform portability which is a very minor issue is most code reuse situations. In C++ cross platform portability may be some added work, but its worth it given the features of the language.
Your preaching Java from the wrong angle and with false pretence.
And then one day, after programming for a long number of years (it may be 2, but thats a long 600+ days!) you realize that it is all gravy.
Yes, coding is just a big pile of your mothers fresh cooked tasty gravy.. mmmmm mmmm yeah..
You see, in the begging was the logic gate. And it gave birth to the integrated circuit. And you programmed those by connecting little wires. And then they sprang forth and multiplied until they were VLSI's which old beardy d00ds and young hacker punks coded with reams of elegant and obscure assmebly calls. And the assembly was a horny bastard, and gave rise to many bastard children like COBOL, Pascal, Lisp, C, Ada, Fortran, C++.. some of them less bastardy than the others..
And upon these good features were taken and incorportated, deriviations thrived.
And you wake up one day and realize that its all a different shade of the same little bits flipping in your logic gates in silicon wafer.
Because, after all, you were just building pieces.. linking them together. Aggregation, Abstraction, Encapsulation, Polymorphism. It was all occuring long before we even knew what is was and in various degrees of completeness.
So you see, the true coder will see the advantages of a OO outlook on development. See its value in addition to the regular, algorithmic logic of proceedural code. And design patterns, objectless design, and all the other future meta abstraction possibilities will have their place as well. They are tools in the coders pocket, ready to use when applicable and well suited to a given task.
We have only begun to build our gleaming cities of logic, and the need for flexible and plentiful abstraction techniques will be a need long into the future. All our pieces today providing for the framework of tomorrows systems.
Flexibility, Extensibility, Reusability are the goals of the far sighted code poet.
Fill your little hacker mind with all the goodness that is rule based, proceedural, OO, and abstract possibility.
Code!
My point was with the proper precautions in place, like code reviews, talented developers with experience, thorough testing and profiling, you CAN eliminate bad code from ever joining your source pool. And everything built on top of that will have a stable foundation.
I do agree that a large number of developers are NOT good coders, and that needs to change. The smart companies hire $50-$100 an hour consultants with extensive experience and form teams with these individuals. You could do the same with selective hiring and thorough evaluations, but nowadays comapnies are so needy for talent that they will accept mediocre developers and ignore the negative impact they may have on the entire development lifecycle.
A talented team and implementing the above precautions will give you a very robust, very stable software system.
You dont understand OOD or OOP with C++. Period. Its blatantly obvious. If you really want to know where your vargs went the way of the dinosaur go pick up a book on OOD. Then think about large software systems. Think about distributed software development. Think about abstracted flexibility and scalability.
Sure, for converting JPEG to TIFF you wouldnt even need an object most likely. That would be a member method of Image which could read any image format and export in any format and all it would take is a
ImageObject.write(gifFIle);
oh, you want a JPEG?
ImageObject.write(jpegFile);
So, do yourself a favor and actually take the time to understand what OOD/OOP is about.
ehehe.. of course! IM NEVER WRONG!!! NEVER!!!
What I found rather amusing is that all C++ supporters on this flamefest were very quick to attack you on grounds of your Code snippets saying you should better learn (a lot) more of C++, without realising that this is the ultimate knockout argument against C++ as a general purpose programming language
C++ isnt a general purpose programming language IMHO. C or PERL would be better for smaller more stand alone parts of computation.
But nothing can touch the power, flexibility, and scalability of well written C++ system. Period. And it is the continual persuit of such systems and their attaintment which makes C++ so popular.
The main point in criticizing this guys code was to highlight the fact that he needs to study OOD/OOP and the C++ language support for these features BEFORE he continues to bash the language itself for its percieved drawbacks.
C++ is not for everyone. It IS an incredibly complicated language. But that is a good thing. It gives you the power to write fast, scalable, flexible systems when used properly.
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.
Yes, that is usually the case. But good design isolates the unknown, variable and yet undiscovered parts from the concrete, well understood elements.
This is where part of your problem lies. The inability to abstract and separate.
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.
No, thats more of a C style development process. Ideally, you would design as much as you could from the known quantities, create the classes and relationships flexible enough to account for the unknowns and then your program can grow with the problem and new situations that arise.
The fact that C++ is compiled SHOULDNT be an issue. Again, your blaming design issues back on the language.
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.
I would say it was an error to undertake this project in C++ with out a thourough understanding of OOD.
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.
Thats a whole other issue. I disagree here as well, but wont go into detail.
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".
That is such an ignorant statement. Think about it. Those petty rules which you violated where common practice for standard C++ development.
The fact that you disregard them so easily is testament to your lack of knowledge with C++ and OOD.
Hey, good tools have been written with assembly! and assmebly sucks for development!
The tool may kick ass... i dont know.
But bad code doesnt ALWAYS mean a bad product. And great, eleagant code doesnt always mean a great product either. They are two separate pieces of the whole, although often related.
DOWN!!! DOWN WITH THE COBOL CODERS AND VB SCRIPT KIDDIES!!! DIIEEEEEE!!!
Ok, you mentioned COM/DCOM?.
Microsoft SUCKS ASS, all their components suck ass, and anyone using their shit best not expect anything that DOESNT suck ass.
If this wasnt a microsoft component, then a review would have caught that error. All of our thrid party libraries and components are thoroughly tested to catch these types of situations.
Furthermore, a review process would have caught that slack consultants code. Period.
Go back to your Visual Basic.
And I think we need to make better coders. There is no reason a technically adept person and the right environment cant produce very stable, very well designed, and very efficient code. No reason at all.
Anything is is a cop out IMHO.
I am most definately an alien species.
.. but all together.
Ok, nice goey CORBA ORB's on linux. What, you code GNOME and now your a professional expert?
If you were to argue cost / time constraints I would conceede the point. That would be the only remotely allowable exception for using untested, third party products and being bumfuzzled when you implement in production, and holy shit batman, our object server dropped core.
Whats done in the real world... hmm... nope.
Anyway, like I said, reviews, testing and skilled coders TOGETHER will provide for very stable, well designed systems. Not just one piece (He was a $100 an hour consultant!) or (It was the IDL Compilers fault!!)
P.S. Do you work with CORBA in a production, real world environment?
I wish I was coding linux candy full time.
But I am currently on a project implementing HA distributed CORBA frameworks for internal software deployment.
We have the framework on HP and SUN, with Java for the GUI interface. This code is written with the above precautions, and we dont have production problems aside from the rare misconfiguration issues which are quickly diagnosed and fixed. Once or twice a month a component will hang, but the HA software and internals catch this as well leaving about 5 minutes of downtime before failover.
So, your assertion that reliable, flexible cannot be written is false. But it isnt easy either.
Allright, your not a VB coder.. I take it back..
One thing that bothers me about C++ protection zealotism (encapsulation, if you will) is that it assumes that behavior is something that can be encapsulated within one class
Wrong! this isnt about bahavior. Its about abstraction and class data member integrity. You are confusing the two.
Putting private: everywhere constrains the code, because it forces particular code to be in a particular class
Wrong! It constrains code by restricting access to private, implementation details. The only public parts of a class should be the interface methods which access the information and functionality represented by the given class. Again, your confusing issues. If you dont want constraints, use C and make everything global! Constraints are your friend, not your enemy.
The result is that half of the code is in a class where it belongs, and the other half is not. Moving the variable to a different class merely switches the halves.
Wrong! This is a design issue, not a language issue. Functionality shared between objects should be abstracted into a separate object, or the two objects collated into one (if appropriate, though not likely in this case). It sounds like what has happened in your case is that you didnt spend enough time upfront with design. Design is much much more important in large OO systems than with any other type of implementation. If you dont do your deisgn right up front, you get problems like you have mentioned.
In any case, my default mode is prototyping, and making everything public. The moment that a reason for encapsulation emerges, I make the relevant variables private, and the compiler catches all encapsulation violations for me. These are usually trivially to upgrade to a new interface.
This is NOT OOP! I repeat, NOT OOP! This is a red headed stepchild of OOP!
In fact, I've read it cover to cover. I learned C++ from it.
There is a difference between reading a book and studying it.
Sorry, but you are a moron. Bye. P.S. Yes I work in a real world enviroment. Scintific data analysis and DAQ code. As well as, in particular, sattelite flight software.
<^>_<(ô ô)>_<^>
It is possible, and in good programming teams,
Yeah, if can hire one. In any large group of people (including our projects team) 80% are morons, and giving thema bazooka to shoot themself in a foot is not a good idea. Problem with runtime safety in C++ - you can not isolate that one moron who have dangling pointers all over him. In a safer language - you give guy an interface and specifications, then run automatic testing on his product, and if it works, it works, you do not worry it will crash...
And good programmers dont write bad code
Wrong. Shit happens. Errors happen. Unsafe code you inherited from somebody else happens.<^>_<(ô ô)>_<^>
Well, let's just wait for good implementations of valarray and slice... Is not it what you want?
As for a mathematical libraries for C++ - here is one commercial one or other one. There are a lot of efforts in high-energy physics community to create some - take a look at CLHEP (well I know it is rudimentary..) or this one. But most of this efforts are pre-standard C++, not using the best features it has to offer (like STL). What do you want - gcc still has no implementation of even - say nothing , and that's the compiler academic comunity (around here at least) uses most. I would expect in the next few years good stable math libraries will appear.<^>_<(ô ô)>_<^>
Nope. A talented team nowdays may well reuse a whole lot of somebodies else code. Is not it the very idea of OO code design. You pop that COM piece in - it crashes you wonderful tested $100/hour code. And BTW some junkies code I had on my hands to fix was by some super expensive consultants. Let's face it, having everything okey-dokey in a big piece of software nowdays is, what your handle says - Pure Fiction. Having it implemented in a languages that isolate potentially bad parts of the code and enforces proper memory access and management solves a TON of potential problems.
<^>_<(ô ô)>_<^>
Slashdot ate my reference to "limits" and "valarray" (where I said gcc (or libstdc++) does even have an implementation of..)
<^>_<(ô ô)>_<^>
It seems to me you are from the other planet. You have no idea whatsoever what you are talking about and is being done in the real world - that's the final diagnosis. And BTW, personally I develop on Linux with CORBA. NOt that it matters for you.
<^>_<(ô ô)>_<^>
I think your an offended VB Scripter that wishes he was coding linux candy... ;)
You can easily find my work if you want. Could you point me to yours?<^>_<(ô ô)>_<^>
One could almost say that the success of a language is measured in the number of proponents of other languages who find it necessary to write "MyLanguage vs. YourLanguage" articles. For Java, there is the already-mentioned digs from Stroustrup, plus what some vocal Perl advocate wrote a few years ago, and IIRC some of the religious Eiffelians tend to spout their mouths off every now and then about how much better their insignificant little plaything is.</flamebait>
All this points to Java as a winner.:-)
Add RougeWave's Tools.h++ to your project and you can play with RWString as well... :-)
You're kidding right ?
How about templates, STL, namespace ?
These feature were not present in the original C++
spec, and now look how Stroustup say STL programming is important.
As for Java, yes, Sun has made quite some change since the beginning... I won't comment as I dislike very much this language.
This is in the FAQ. Go and check it out - it is quite interesting.
-- Word of the day: Percussive maintenance is the fine art of whacking the crap out of an electronic device to get it wo
I would say they should learn them at some point during the neophyte stage of developerhood. There are computer engineers and computer science majors just graduating that don't know how memory allocation and memory management work, and they're unaware that their use of language features can have any affect on runtime. I work on a project that develops OS-like things, and we're seeing a barrage of new grads that are confused by having to do their own memory management or pay attention to what language features actually do. There were actually some fairly bright people interviewed recently that had to have pointers explained to them.
I completely agree with you that understanding the underlying implementation for most languages can be critical in implementing algorithms efficiently. No less than Donald Knuth makes this clear when he insisted that a low level assembly language, MMIX, still be used when revising TAoCP Vols I-III.
Not knowing how to use a pointer pretty much rules a person out as an embedded developer, compiler-writer, operating system developer, as well as many other things. Hell, even for programming in a language that doesn't explicitly have pointers, and that has garbage collection, I'd still like the person to know how to work with memory.
It is far from clear that pointers and pointer arithmetic are the best way to teach memory management concepts. Just because many MM implementations have used pointers to date doesn't mean that it's the only, or even best, way to understand the underlying concepts.
If you are doing code maintenance, then odds are good your work will involve looking at somebody else's pointer code. But just because I was able to figure out somebody else's 1960s-style
As far as I can tell, you're getting an ability to understand the lower level abstractions and implementations confused with the ability to use them directly when programming. The first is desirable, whereas the second is often contrary to OOP. Of all the examples you gave of where pointer techniques are "required", about the only two where I think you can make a good case are maybe the memory management portion of an OS, and some types of real-time code. In most other cases, better designed higher-level abstractions will usually be a better fit; however, you will have to be able to understand what is going on at the lower level to be able to design those higher level abstractions properly.
Laissez lire, et laissez danser; ces deux amusements ne feront jamais de mal au monde. - Voltaire
i doubt he did it to make another buck or two, it sounded a lot more like he was trying to point out where you could find more info where the complete explanation was too long to write in this interview.
Should I infer from this that there is a ++C language, which does not call the C language copy constructor - yielding an improved version of C without the (almost) complete backward compatibility?
:)
Send me the URL!
Actually, I usually call C "Straight C", I may have to start calling it "Old C" though, just so I can be as insulting as I can. Perhaps "backwards-thinking C" (Or C--) :P
[ c h a d   o k e r e ]
ReadThe ReflectionEngine, a cyberpunk style n
Why don't you just register a new nic, that way you'd start out at +1 instaid of +0.
[ c h a d   o k e r e ]
ReadThe ReflectionEngine, a cyberpunk style n
They were using serverside HTML on apache, as that the standard error message. I know that wasn't really the point of your post... but...
[ c h a d   o k e r e ]
ReadThe ReflectionEngine, a cyberpunk style n
obviously.
sorry, but your opinion simply is silly.
Your java programming competition will be very happy.
> But remember that for the first 8 - 10 years of C++
Java: a language that grows as its user base becomes more and more demanding...
C++: the same, only 8-10 years older.
Sorry, I can't afford to wait 8-10 years to find myself more or less where I am now, only with a different language.
> I guess you did not have enough pain fixing other people's code
Strangely enough, it's exactly what have been doing in the last two years and a half: maintenance of other people's C++ code.
And still I'm grateful that I have every dirtiness of C++ at hand to avoid myself major rewritings in the night, and if things are broken, I could always throw in another upper layer until the bottom one is rewritten. Cyclic developement. Usually works.
Personally, I believe that Java allows one to avoid only simple mistakes (syntax, style) that one sorts out in 6 months or so, not major ones (design), which takes years of experience. With the features of C++ and the existing tools (mostly Purify) I'm able to circumnvent quite easily even serious mistakes, like a sort of swiss knife that you may cut yourself with, but usually helps a lot to get working things delivered within schedule. I don't seriously believe that Java would be of great help here (unless I'd run every source through m4, but that's another story).
> You would be absolutely right if the world would only consist of code masters
I'm for an impact therapy: put newbie developers in front of their responsibilities, expecially when they work in a team of 10+ people with all of them needing to be able to read each other's code. Don't ever put them in the condition of feeling inadequate for the job: if the task is too complex for them, choose a simplier one that would fit.
Submit them to peer reviews, the sooner the better.
Suddenly, one quickly realizes that fiddling with new paradigms/styles/etc. which he is not absolutely sure and self-confident about has necessarily to be done at home in spare time if one really wants to... not at work. Slow? Yes, but gives better results in the long term.
But perhaps in the USA being on salary is not convenient anymore... and as a freelance programmer one has to put out something working - no matter how he did it - since the very start. You see what's wrong with that philosophy? One learns to code as fast as possiblle without regarding design (and sane grocking over things before writing code) and maintenance issues.
> Speed of execution isn't always important
Of course, fortunately.
But hearing that from an hardware manifacturer & vendor (Sun) makes me a little suspicious. I know that when UNIX has been rewrote in C from assembly, a 30% of performance was lost in the way, but the advantages in portability and maintenance were huge compared to that. Does Java offer equal advantages? As today, I wouldn't be so sure.
>Is [] just an array or is an overloaded operator that makes some non-obvious assumptions?
"obj.grokThisThatWay()" does really do what it says to do? Does it says anything useful about its invariants? What keeps one using misleading names for symbols keeps also a C++ programmer to abuse operator overloading. If the object on which you overload the [] operator is not assimilable to a collection of some sort and what's in between the square brackets is not an index or a key of some sort used to retry a value from that collection, you interface is flawed no more and no less than if you called all your methods "foo()", "bar()" and "baz()", perhaps with misleading comments. And you won't notice it until it happens to you to use them.
> With MI if I hadd something to one of the base class, what happens especially if there are conflicting names?
MI is mainly used exactly as in Java and exactly as Bjarne said: as a way to implement multiple interfaces (abstract classes made only of pure virtual methods). Only you don't need two additional keywords to do that. If you want to use it in any other way, it's your problem, not mine.
And if someone points out that it's inherently leads away from code reuse, I'd reply that throwing code out of the window from time to time is healthy, because there are few designs that lasts immutate for 10+ years (unless you spend in absurde quantities of money and it happens to you to have a monopoly of some sort, or you are really clever). Until today, Java made that period even shorter for reasons that are not related with software design, but with the design of Java itself.
> It is almost difficult to make a Java program that is difficult to understand
It's equally difficult to make a C++ program that is difficult to understand, unless the design is really, really bad. But, for now, it's easier to get stuck with Java than with C++.
+++
Sometimes, it seems to me that some Java enthusiasts are seeking (with pain) for the One True Coding Style That Fits For All Useful Purpouses(TM), which is obviously hopeless, and incessantly compare Java with other languages not by its merits, but for What They Assume It Is Flawed With Language Foo Because They Instinctively Would Use It In A Flawed Way.
Relying on features missing (or imposed) don't seems to me a good strategy in the long time. Strangely enough no one ever mentions a real flaw of ANSI C and C++: guess what? Trigraphs, of course. They are there. Does anybody actually uses them? No, of course. You see, you don't need to use every feature a language offers if you don't need it. A so-called programmer should be able to distinguish by himself the situations in which a certain feature is useful, otherwise it wouldn't be a programmer, but a brainless code droid.
Really, I used to have a predilection for Java in the past. Now I regard it as nothing more than Another Respectable Language Which Has Its Grade Of Suckness Like Every Other Language Out There. 'nuff said.
My 0.02 Euro.
That's not standard C++ anymore, GCC will give a warning now.
I have seen the future, and it is inconvenient.
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 there is a great deal of confusion caused by C++'s resemblance to C. There is a whole different way of thinking involved in using an object oriented paradigm versus a functional one. I've seen so many functionally thinking programmers learn C++ in an effort to broaden their horizons without really taking the time to understand the difference. This leads to situations such as not knowing how to use classes properly. There are some who seem to think that classes are just C++'s way of doing a struct, much less appreciate templates. They start to make assumptions about some of C++'s features by trying to equate them to C's features, such as using streams in place of printf. But then they fail to recognize the power of these features and try to use them just like they would in C. This creates all sorts of ugly code and usually leaves the programmer with a feeling that C++ is too complicated to be worth it.
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.
It has always been a matter of vendor implementation. The language itself started out reasonably strong and has grown stronger. The big stumbling blocks were vague areas of the language that vendors chose define (and sometimes rely on) and how efficient the compilers and linkers have been. Of course, the more experience a vendor has at creating programming utilites, the more efficient they tend to be as long as you don't try to keep cramming more crap into them (hello MS).
-Jennifer
seen in the g77 (GNU Fortran 77) documentation:
# info -f g77 M LEX
if the file contains lots of strange-looking characters, it might be APL source code; if it contains lots of parentheses, it might be Lisp source code; if it contains lots of bugs, it might be C++ source code.
No, your implication, that writing code means learning how to write it well. Surely, you will improve in your coding skill, but that's not the same as activlely searching for and learning how to do something right.
Especially that he wrote it alone (if he really did?!?), as you say, would rather explain why code could be bad. If you have to work together with others, you will faster get new ideas how to solve problems more elegantly.
Btw, I don't mean to know whether the original poster knows C++ well, I just wanted to put your comment into a different light.
Keep an eye on which arguments are silently dropped in replies. Not always, but often times it's very telling.
yep. i like to think of Java as C++ done right. The 1.1/1.2 java versions are perfectly useable and lead to decent code in a decent size. the speed will improve eventually..but it rocks as a language.
Byarne Straw stroop
Byarne: By like in Bjork, pronounce the ne like a porn star (nuh! nuh!)
Straw: more like stroh, actually
stroop: oo as in book
Hands in my pocket
I truely belive that a mix of programming languages and methodologies is needed. Deciding on the mix is dependant on the project/problem at hand.
Often the choice of the mix will determine the outcome of a project more than the actual implementation.
For instance you take a huge project (200,000+ lines of code, not white spaces or comments). You have 20 programmers working on this project. Are all of them going to have the same skill set? Some are going to have a better grasp of OOP and some better at structured programming. This is where a good manager comes into play. He should be able to recognise who has what skills and devide the team accordingly. During this process the manager needs to find the people with strong aptitude towads the metholodigies which are going to interact and put them in charge of the interface of thoes metholodigies.
After the team has been devided then the proper tools for a correct solution needs to be selected. The programmers selected to be in charge of the interfaces should be the ones to select the tools/languages based on the expertise in each of the teams.
With a good mix of the above situation any software project is destined to be a success. I have personally been involved with a project of the one described and the results were phenominal! We used assembler, c and c++ with carefully designed interfaces. Each team had somebody who was extremely adept in what his team was working on and what his team was going to be interfacing with. The team was made up of the people who's aptitude mostly fit with the particular team. There were varying degrees of aptitude in which the expirenced tackeled the more complex problems and the novice tackeled the simpler problems or assisted the more expirenced.
Sadly I've not found this situation outside the college environment. The above mentioned project was with an unmanned aerial-vehicle competition. Most of the students were there for the fun of it. The project was to designe an aerial-vehicle to map a simulateed a toxic wast field. Finding and diferentiating(SP) between barrels with either a raidoactive or biohazerdous symbol on them. There were quite a few disperate subsystems which exsisted. Mainly communications from the vehicle to the ground station. The vision system and the acompying software. The navigation system... In one year we built a system that took 3rd place in an internationl competition held at Eppcot Center Orlando Florida.
Of course this type of environment needs decient people who know where their programming aptitude stands and not take offence to working on a simpler problem.
If at first you don't succeed, skydiving is not for you.
Have you tried kdbg
It has been statistically shown that helmets increase the risk of head injury.
I wholeheartly agree with you, C++ is far from being the best solution when you realize there is something else than C and its pointers around.
;-).
However, no question on the potential flaws of C++ made it through moderation, so of course you can conclude it's the ultimate language
The guy responding to you was pretty harsh. But, he was essentially correct. The contorted examples you gave really did indicate that you don't understand (or prefer not to use) the newer elements in C++ like templates, function objects and the STL.
However, I don't think that anyone is saying that C++ is the perfect language for everything. For dynamic tweakability, it's hard to beat lisp dialects (look at the success of Emacs) or Python, as you indicate. I might even go so far as to say that one should prefer simpler, dynamic languages except in areas where performance becomes and issuue. That's why it's often good to use two languages on a project -- a fast language for the 'engine', and a dynamic language that supports easy configuration for the rest.
Stephen Molitor steve_molitor@yahoo.com
"Obviously you are unaware of the finalize method you can declare to do exactly what you want."
I think he wants to be able to ensure that a resource gets freed immediately when an object goes out of scope. You can't do that with finalize. Finalize just guarantees that the resource will get freed sometime.
For example, lets say I have an object that opens a file. I could use finalize to make sure the file gets closed, but I'm not sure when that's going to happen. That file might be and important resource that I want to get freed immediately after my object goes out of scope (and can't possibly use the file anymore), so that other objects can open the file. C++'s destructor mechanism guarantees that; finalize just guarantees that the file will be closed sometime before the program exits.
Stephen Molitor steve_molitor@yahoo.com
"I don't see how the destructor mechanism guarantees anything since you still have to make sure it is called yourself."
In C++, the destructor is ALWAYS called when the object goes out of scope. You NEVER have to call destructors yourself; it's usually considered very bad form to do so. That's why destructors provide a guarantee in C++. So, you don't need try...finally in C++ -- the destructor takes the place of the finally block. Destructors are always called (guaranteed), and you know exactly when they will be called. You can accomplish the same thing in Java with try...finally, but you have to litter your code with try...finally blocks. In C++, a resource is encapsulated as an object, and you only have to write the cleanup code in the destructor once. And you NEVER have to call it yourself. I repeat -- you do NOT have to make sure its called yourself. Destructors are automatically called when the variable goes out of scope.
I'm not sure how pointing out the differences between Java and C++ regarding resource handling (and having an accurate understading of those differences) translates into trying to do C++ style programming in Java. Undestanding the differences between the two languages would seem to be the way to AVOID misapplying approaches that are appropriate in one language to the other. Perhaps if I misunderstood C++ as much as you do, that would make me a more "Java" style programmer?
Stephen Molitor steve_molitor@yahoo.com
"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)."
Exactly. I know that -- in Java you don't know exactly when destructors will be called, so you can't use them to manage resources. You can't truly encapsulate a resource as an object via Java. I'm not saying I would try to do this in Java. I might want to, but I can't. In Java, if you needed to control exactly when a resource gets freed (and this happens, especially for non-memory related resources), you have to use try..finally, not the destructor (since it won't do what you want). C++ is nicer than Java is this respect.
Please tell me where I have made inaccurate statements about Java. I think I understand Java's approach to resource allocation, destructors, etc., pretty well.
Stephen Molitor steve_molitor@yahoo.com
Absolutely! One of the reasons I like Python so much is that working with it is like working with ObjC.
What I found rather amusing is that all C++ supporters on this flamefest were very quick to attack you on grounds of your Code snippets saying you should better learn (a lot) more of C++, without realising that this is the ultimate knockout argument against C++ as a general purpose programming language. One is probably able to do everything in C++ what can be done in Scheme, Python, ObjC, Java,C or whatever... But to do it in a natural, easy to grasp way your really have to be familiar with C++ to an amount that only few of us will ever achieve. Looking at 1200+ pages of the "C++ Primer" makes me shiver... Man, exactly how much do I NOT know of this monster of a programming language? But I'm still using - and struggling with - it.
Cheers
C++ isnt a general purpose programming language IMHO. C or PERL would be better for smaller more stand alone parts of computation.
But sadly a lot of students even have to learn C++ as first programming language, something I think is just plainly wrong. Of course teaching them perl would be much worse...
But nothing can touch the power, flexibility, and scalability of well written C++ system. Period. And it is the continual persuit of such systems and their attaintment which makes C++ so popular.
Well, that's IYHO of course. Myself I have yet to see something remotely as elegant and powerful as Openstep implemented in C++.
C++ is not for everyone. It IS an incredibly complicated language. But that is a good thing.
It gives you the power to write fast, scalable, flexible systems when used properly.
But if it's such an incredibly complicated language why even bother with it? (provoking statement, I know). Wouldn't we not all be a lot more productive if modern programming languages were a lot easier to learn, grasp and use?
I definately agree. I think people who learn procedural programming first make better OO programmers in the long run--they are much more likely to understand the benefits, limitation, and tradeoffs associated with using those OO features that people who start off in C++ overuse, or use poorly.
Personally, the thing I dislike about C++ (and Java even more so) is that it turns too many warnings into errors. Computers exist for me to tell what to do, not the other way around, and if I write something that is syntactically correct and well defined, a compiler has no business telling me I can't do it. Yes, I even thing that accessing a private member of a class should only be a warning... If I have a legitimate cause to use a classes private variables, don't make me "#define private public"
- Aphelion (an image processing library) used AphString in their C++ code.
- Aphelion, the same damn library, used char* in many parts of their library that was based on KBVision, an old product of theirs. Notice it was a char* - not a const - so the other string classes were not automatically converted.
- C++ standard string class.
- mfc's CString.
Anybody got that beat? So much for the Pragmatic Programmer's "Don't Repeat Yourself" principle.Hmm, for the past few months I've been programming Java (after using C++ for some time) and I have to say its syntax is completely spoiled by the type casts that need to be all over the place. As Bjarne said, the lack of MI in a strongly typed language means typecasts, everywhere. Especially since no such thing as templates exists. Brrrr.
All containers (such as Lists) are containers of Ojbects. You must cast those back to what they were, each time with the risk of a Class-mismatch (causing exceptions). Not only is this ugly, you also loose all advantage of a strongly typed language.
GDB is the greatest. What should I use instead...
dbx...xdb...or some graphical thing. What debugger do you know that accepts things like
c 100 to skip this breakpoint the next 99 times. Great when doing things like looking for a certain record in a file.
May your soul reach heaven before the devil realizes you are dead
I notice that Bjarne mentions this in passing, but doesn't elaborate. It is this issue that prevents a solid ABI based on C++ that sues calss inheritance.
The first language I learned was BASIC. 2nd was Cobol, 3rd Fortran, and then C++. Although I'll never be awarded a Nobel prize for my programming skills, I guess I'm a fair C++ programmer. BTW, I skipped "traditional" C altogether. Funny thing is/was that, I didn't realize that C++ was too complex to be useful, taught properly, implemted correctly, etc..etc.. until somebody told me. Too late now. C++ and (OOP for anything larger than a couple of hundred lines of code) are basically all I know. Thanks for enlightening me on the deficiency of C++. Maybe I could go back and learn C and revert to strictly procedural paradigms.
Does a jock itch?
Although we are getting a little off-topic here,
I think that you're not 100% correct in your assertion that C++ can't handle computational mathematics. Although not a expert in this area,
I know a few who are. They use C++ extensively for scientific computation at AFIT, (Air Force Institute of Technology), and could probably help you out if you wish. Hell, they even use PYTHON, to some extent, with hellish embellishments and self written library's. If you're interested, e-mail Jbythelake@yahoo.com, and I'll give you my "real" e-mail address, and link you to them.
I disagree with you on one point, though, for the years invested in learning C++, OOP, and proper design and use of the intended features, I'd probably stick to FORTRAN. Although I've only used it to a limited extent in engineering applications, and by no means extensive "brain-wracking" computations, it sure seems a lot more simple to use.
Does a jock itch?
But I have to agree with you on the template stuff though. All those stupid casts where you really KNOW what type everything is of. Plain silly. Either use a weakly typed language or non-awfull template implementations. But MI would in no way solve this problem.
Try out fish, the friendly interactive shell.
I was a moderator Monday, and I thought the fake inverview was funny. ;)
Hosting for Creators: http://rpg-works.net
Since Java was released less than 5 years ago, are you a member of the original team?
Or are you displaying the same pension for accuracy displayed in the original post?
The language was originally designed for the embedded, standalone device market. The original effort was a C++ compiler, but the Green Team decided C++ was not a good language for that product space.
Java was a C++ like language with the most error prone features taken out.
The requirements of the embedded, standalone market closely match those of a networked, distributed world, and that has made all the difference in Java's acceptance.
Wow, he's even more of a man than I thought. That little section on Java in his FAQ rules. What a bad man. Damn, this whole /. interview thing kicks ass.
To put in my $.02 on the flamewars... I'm one of those system-level thinkers someone mentioned earlier. I draw blocks and arrows for a living. Ie, OO styles work best for me, for the kind of programs (event-driven simulators, program understanding tools) I need to write. If I were to write a device driver, or OS kernel, I'd probably use C. I certainly wouldn't use it for a large, complex program, though. The biggest reason is that the program structure is too hard to document; maintenance happens, folks, just not with C. Use the right tool for the right job.
And when I want to program for fun, I write in Scheme. :)
I am a man of const int sorrows
More from Stroustrup on Java:
l )
Q: What is your take on the Java revolution?
A: What Java revolution?
(read the complete interview by Chuck Allison from the C/C++ Journal,
1996, at http://www.research.att.com/~bs/cuj_interview.htm
You mention how Python can save lines of code. In your example, this is true because Python is not doing strong type checking. C++, and other strongly typed languages are forcing you to be very explicit about types.
So why not just use Python? I can't tell you how many times strong typing has helped me debug a sophisticated data structure.
Also, sooner or later, you're going to run into speed problems in a music type-setting program. Some speed cost is inherent in the fact that your language isn't strongly typed (-: You want to '+' two items? Well, are they strings are ints? In one case, you concatenate and in another you integer add. For strongly typed languages, the compiler would have known at compile time and already included the correct operations. If you've gotten away without specifying a type up until this moment...
Some really, really interesting stuff. I'm going to forward this to everyone at work here.
/. for getting this great interview!
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
Buses stop at a bus station
Trains stop at a train station
On my desk there's a workstation....
Um, why do you think it's an abomination?? Don't just shot something down without giving a reason. What projects have you participated in using C++ that have failed so much or left such a sour taste? I'm assuming that you have used C++ for something and haven't just read the book and then burned it.
Buses stop at a bus station
Trains stop at a train station
On my desk there's a workstation....
What They Assume It Is Flawed With Language Foo Because They Instinctively Would Use It In A Flawed Way ... You know, for every senior (clueful) programmer there are 5 (clueless) programmers out there and they do tend to misuse the so easily misused language features they have just learned about on some quick course. You would be absolutely right if the world would only consist of code masters, but it does not seem to be the case unfortunately.
I guess you did not have enough pain fixing other people's code
I used both C++ and Java regularly and I can say that both languages have definite advantages. On one hand, Java is a safer language to program in. It does not allow pointers, implicit booleans with ints, has garbage collection built in, ...
These things being said, Java is a beast. In it's current state, I don't think any serious programmer is going to design a program that requires any sort of high performance execution in Java. C++, on the other hand, does efficiency very well. When used correctly, it can also be reliable, leaner, meaner, and trimmer than Java. The features that are dangerous were mostly inherited from C, and it was a realists design decision, rather than an OO purists. From reading BJarnes comments, I don't think he was after being "pure" anyway.
Another defense of C++ is templates, templates, templates. Everywhere in Java, you have all sorts of casting everywhere. To clone you have to cast, to get an element of a specific type out of a Vector you have to cast, etc... Aside from being just plain ugly, this also introduces more Runtime ClassCastExceptions that could be avoided. Another reason Java is more bloated looking is the lack of operator overloading. Here is a good example of Java code bloating.
Java:
// define a Vector
//
int i=((Integer)v.elementAt(1)).intValue();
C++:
// define a vector
//
int i=v[1];
These issues are way oversimplified, but these are some important ones. Overall I think the final decision to use one or the other depends on the project, and the coder. The project because some things such as system programming cannot be done in Java. The coder because the languages operate on different philosophies. Java's philosophy is that it doesn't trust the coder. Since other people have made mistakes with useful features in the past, it just got rid of them. C++ is feature rich, gives you a lot of options, and let's you break your own neck with them if you want to. Java gives you training wheels so that you can't do that. Once you mature as a coder, you won't need them as much, and you will start getting really annoyed with them when your doing the Iron Man.
>> 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.....
I can confirm that... I came to C++ from Java. I did learn some BASIC first, but I've almost forgotten it. Nobody ever taught me what was good functional programming style. However, my degree course was based around Java and OO programming.
When faced with C++ I was able to make the conversion fairly painlessly: it wasn't the objects that were the problem, just the pointers! At this stage my C++ may or may not be a very good style example (I hope it is!) but I know it's better than anything I could hope to write in C after a similar learning time. I just don't know how to write functional programs. I'd be forever trying to write C++ in C, rather than getting on with learning C and writing that instead - just the mistake C programmers make when they learn C++. Only, there are plenty of trendy texts explaining OO style to C programmers, and a lot less explaining functional programming to OO programmers.
> 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?
// a null reference
That's the one thing that I miss from Java - not being able to say
class Jobby{
public:
MyObject& anObject;
Jobby(MyObject obj);
}
Jobby::Jobby(MyObject obj){
anObject = obj;
}
Perhaps being a Javaist makes me overly wary of pointers. But I _like_ references!! And I don't like that nasty -> thing!
C++ C + 2
I bet you meant to say, C++ < C + 2
Right?
So, your very(!) lengthy and thorough post boils down to this: The difference between C++ and Java is like the difference between Linux and Windows. Windows - far easier to learn, a wealth of libraries (which may be unoptimized, but functional), and much harder to shoot yourself in the foot with. Linux - very flexible, will do anything you tell it to, but it never asks you "Are you sure?" and which assumes the user is experienced enough to know how to at least RTFM. I was the first person to write production Java for my company. This means I had no one to help me out with the pitfalls/dangers of programming. I do not believe I could have done (on schedule) the projects I was assigned in any other language (as I was not an experienced programmer). So, Java made me a hero, and I like that. Paychecks are nice.
"We apologize for the inconvenience."
I hear you there...If I was so foolish as to be doing client-side Java (read: applets, event model 1.0) I'd be screwed. I wasn't too pleased with JDBC before version 2 either. And if I'd written enterprise beans with the 1.0 version, and had to migrate to version 1.1, again I would be screwed. But that's the price you pay for bleeding edge evolving standards. The nice thing was/is that Java API is easy to read and learn. Even the totally hosed-up 1.0 event model taught me lots of important lessons about object modeling (with no previous OO experience).
"We apologize for the inconvenience."
It is complex but I have never seen it taught right in the first place. I taught myself C++ when I was twelve. I took APCS as a highschool freshman and the teacher didn't know how a for loop worked. I passed the AB APCS test thought because I already knew the language. Now I am taking it again because i missed the first two weeks and because i took it during my independant study. This time the teacher knows how to write a loop but she is pretty pitiful to. She has made very many errors while she was teaching and I have a very good feeling that she does not know crap about what she is talking about. She doesn't even know what to teach the fscking students for the APCS test. And I don't have a say in it so hopefully it won't be offered again because anyone that acutally knows the lanugage isn't going to be teaching!
Well, all politics aside, I'm just saying that I like the language. I like how it's an object-based language. Everything is a descendent of the Object class. This makes me very happy. I like how the language is simple. No ambiguities about things like where to place "const", like in C. No preprocessor madness. I like not having to worry too much about memory management. I like the libraries that come with JDK 1.2. I like it all, man. I just wish it was a bit faster.
while (cin)
{
- cin >> word;
}word_positions[word].push_back((int)cin.tellg() - word.size());
Now I actually agree with every one of your points about Java, and I'm not starting a flame war here. But it is a very important point to note that even C++ has some bizzare idioms. Your c++ code given above has a bug: go ahead an run it on a test file. It won't work: the final word will be printed twice, with an incorrect position the second time. The correct code is the following:
while ( cin >> word )
{
- word_positions[word].push_back((int)cin.tellg() - word.size());
}For /. readers who don't know what the value of the expression 'cin >> word' is, please read Stroustrup's book before responding. It evaluates to a bool, NOT the value of word. The bug in the first version has to do with exactly when the eof bit of the stream is set. So C++ makes it nearly impossible to do something very trivial correctly. Pretty scary stuff, eh? For all I know, even my version of the program might not work in some bizarre scenario. I'd have to check, cause the manpages sure don't document things precisely enough.
In contrast, Algol 68 provides a wide variety of possible operator symbols--and if C assignment operators yielded reference modes like Algol 68 assignment operators, it would be convenient to use the operators for I/O that actually carry the connotations that make sense, += and -= (doing output appends to a stream, doing input removes something from it.
gcc.gnu.org
... :-)
sourceware.cygnus.com/libstdc++
One of the best compilers.
If you have $$$, SGI's MIPSpro (7.3.5 or later) is good, as is KAI C++.
But gcc gives the most bang for the buck
I am currently a first-year comp-sci student who is learning/learned c++. The book(s) that I have used have in my opinion sucked and did not explain templates at all. Can anyone suggest a good c++ book? I understand that Bjarne's book, whatever the name is, is not a pure programming book- but would his book help me understand templates?
Real men dump cores! Read my journal, I am neat.
I'm tempted to think some of the problem is schools that introduce programming with C++. University CS departments seem to be doing this quite often, I guess because students don't want to learn a language that's not going to earn them big bucks ASAP (and it's hard to blame them since they need to get internships or part-time jobs, and this is not easy if all you know is Pascal). I learned to program with BASIC (yes, a long time ago, 1981) and Fortran77, and I think this helped a lot when I began learning C++. Intro to Programming courses that utilize C++ seem to be so focused on the language (because, yes, it is complex) that programming techniques become a side issue at best. I really like the language, but it's hard for me to believe it's the correct one to start with.
For the very reasons he stated GTK SUCKS. They tried to produce a class structure with a language that does not support classes. For this very reason GTK is both slow and non flexible. QT smokes GTK due to its great object design.
Ernie
More race stuff in one place,
than any one place on the net.
The AS/400 is many things, but slow isn't one of them. This tells me that high performance, system level programming is indeed possible with C++. I suppose it is easier when you are designing the hardware and software, and you can build a closed system. But still, I agree with Bjarne. C++ can be used at the system level even in an open system, as long as programmers are mindful of what they are doing.
?
Ive already taken a few deliberate moderation hits today to be goofy but this is awesome :-) I love when /. gets people like Bjarne to do interviews. Makes me feel all warm and fuzzy inside. This is content generation at its best! :-)
The good ol' F77 LAPACK is a haven for all of those who need to do matrix math. Granted, there is a f2c'd version of LAPACK for C, but it involves playing all sorts of obnoxious memory games, as F77 doesn't support dynamic memory allocation. I don't like allocating tremendous arrays to pass to FORTRAN routines for work space.
C++ has nothing that comes close to an analog for LAPACK, and the standard support for less specialized computational mathematics is limited as well. The STL has no implementation for a Matrix, and its Vector implementation leaves a lot to be desired , from a mathematician's point of view. C++ can't be all things to all people, but I would love to see a serious mathematical library developed for C++. Cross linking with FORTRAN is a pain in the rear.
As far as OOP is concerned, that is a number of language far better than C++, by 'better' I mean more compact, consistent, and less confusing. Why bother with C++ then? I"ve been hearing 'because it inforces the programming's discipline whereas C doesn't. Give me a break. A lack of programming discipline is something you can't just inforce with a particular language, right to the contrary, a language such as C++ or Perl, both feature rich and both confusing as hell don't do anything toward better programming discipline. In short, C++ is abomination. A crime against nature.
I remember seeing someone his comment on Java. He just don't get it! 'Don't understand what all fuzz is all about' or something like that ...
Amen, brother ...
What is the point?
Here's how I see the differences between C++: A) a lot of useless abstraction and B) a lot of things you CAN do in C, you CAN'T do in C++. What is the point of all this? Near as I can tell, it was designed for managers. Managers looked at C, which is an elegant, excellently defined language, and had a few problems with it:
My conclusion: The number one reason anyone picked C++ in the first place was because they went to a store, and side by side they had 'C' and they had 'C++'. Which one is obviously better? Which one is the more advanced? Which one is the more MODERN AND PROGRESSIVE? Obviously the one with the ++ on it. MORE IS BETTER.
Managers want a language that restricts programmers from doing interesting things, and has more buzzwords and hype surrounding it. Programmers who go to all the trouble of learning all the insane abstraction and crap that surrounds C++ want to feel like they've invested their time wisely and are a valuable contribution to a workforce. Thus, C++ is clearly superior to C; C is just too simple, too elegant, and too direct.
I am tired of this crap. I love and respect the C language; it has a well-defined structure that works like a human language, in that it can have its own idioms, cool grammatic twists, etc that are all correct but all very interpretive. It is SO simple. I simply don't see the point in any language that takes more than 10 pages to document.
C++ is a manager's language; it is a hype artist's language; it is the language of people who aren't satisfied with using something simple and have to go clutter it up to satisfy their ego.
I realise C is falling in the face of C++. I find this incredibly sad. Is there any reason for this? No. Please, will someone explain to me where my poor variable-size argument lists went? Please explain to me why I have to prototype everything (and on and on) ... Please explain to me why I need 'objects' and 'templates' if I want to write a program that, say, converts JPEG to TIFF. I mean, hell, if you're writing some huge crappy Windows app, maybe you need it. But if you're being sensible and writing a set of small, clean programs that interact well with each other, why do you need all this object shit? COMPUTERS ARE NOT OBJECT-ORIENTED; NEITHER SHOULD PROGRAMMING LANGUAGES BE. When I do something in C, I know pretty precisely how the computer is going to behave; when I do something in C++, I haven't a clue. I can't pass a fucking function pointer outside of an object and expect other objects to be able to execute that function. WHY NOT?? I mean, the fucking memory is there, it's at the right address, I should be able to execute any fucking address in my memory space. But in the name of progress, everyone wants of course to adopt a language that actually lets them do LESS. Typical.
This is not flamebait. I am just incredibly tired of this hyped up, crap language. Don't you people have any respect for C and what it can do? Would you rather be writing in COBOL? Pretty soon, we will be programming not with this 'old' concept of object-orientation, but with the new paradigm of 'warm pink fuzzies'. 'Warm pink fuzzies are very useful, you see, they are the next big thing... Unfortunately, we have had to maintain compatibility with this primitive language called C++, but....'
C program using cout You don't know what the hell you are talking about, do you ?
I've also used Objective-C, and must say that it produced some of the most unreadable code I've ever seen, in part because people didn't feel the need to write comments. The other part is that prototypes are optional and there is no access control. If you can name a function, you can call it. This does not encourage readable code. Objective-C also doesn't fix some of the same parts of C that C++ doesn't fix (declarator syntax and others). Java, on the other hand, puts the best parts of Objective-C into a reasonable syntax. It'll be interesting to see how efficient the GCC Java front-end ends up being.
On one end of the scale we have the abstractionists who think in terms of the big picture design and 'see' projects in terms of components that interact with each othere. They are easy to spot in meetings because they are always the ones that tend to draw lots of UML and convoluted design graphs and they don't talk to people who haven't read the Gang of Four.
On the other end of the scale we have 'bit fiddlers' (sorry i find this expression rather amuzing). These guys tend to worry about the low level implementation details and often think in terms of actual lines of code and often ignor the design issues. They are very good however, at spotting design flaws that make the implementation hard.
Now, the problems lies not in the fact that we have these two groups of coder (see which category you fall into) but because these groups don't interact with each other very well. The abstractionists find it irritating that the implementationists don't see the 'big picture'. On the other hand the Bit Fiddlers get frustrated because abstractionists tend to overlook implementation issues. However, it takes both groups for a healthy software engineering project to thrive in my opinion.
What I find is that abstractionists tend to like and 'get' C++ more because of the natural gift of abstracting their ideas. The implementationists prefer C because they live in a constant fear of what happens 'under the hood'. That's why they lean towards C. Having said that you do find abstractionists coding graphics pipelines and implementationists writing C++ frameworks. Unfortunately the results are often mediocre in such cases. So to summarise this already prohibitively long post I'd say find out what category you fall into and choose the language for you. You'll feel more comfortable and your code will thank you for it :-).
this post is "Informative" -since when moderators are funny? this is informative! sure it is! o0
Istigkeit -"is-ness" being and becoming & i'dfiying it with the mathematical abstraction of the idea
I would grant you that it is easy to write and read, but it suffers from bad association with the horrible compiler that apple puts out for NT. God am I glad I don't have to work with that everyday anymore. I never had a chance to try the compiler on the MACH system or on a MAC but I have been told by people who have that the IDE is weak compared to Visual Studio/Borland Builder type IDEs. Of course I do most of my programming on a SUN system without an IDE so that is not terrible critical. Now that I think about it, it was the IDE and WebObjects together that was buggy. Just random thoughts. Forgive.
I feel differently. (C:
GNOME is C; KDE is C++. Both projects have done extremely well. I would hesitate to say that the difference between C and C++ has affected the two projects at all.
This is because few people learn the language in order to contribute to the project. Most of the interesting contributions to either project have come from people who knew C or C++ beforehand.
I don't think people use char *'s and structs and write
their own vectors because they are too lazy to use the
STL. It seems like so many compilers don't even come
with it!! We use Sun's C++ compiler and it comes
bundled with RogueWave instead, and frankly RogueWave
sucks, especially if you are trying to write code that
ports to win32. Frustration with mediocre libs is what
drives me to use my own low-level C constructs.
* Bjarne writes:
*
* 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.
void draw_all(list<Shape*>& lst)
{
for_each(lst.begin(),lst.end(),mem_fun(&Shape::
}
--
"NT: taskmanager is not responding"
soon the standard will require you to return an int. Plus its nice to tell the user of the program the exit code (ever write a shell script?)
Anonymous posts are filtered.
pretty much every debugger I've seen will do that. VC++ will even let you specify the condition on which to break within the debugger. Have you ever done any work where a graphical display of the data would have been of any help? DDD is good at that sort of thing, the Insight debugger is also good.
Anonymous posts are filtered.
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
Sheesh, that's enough to make me want to learn Java instead :-).
-E
Send mail here if you want to reach me.
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'm not a smorgasbord.
I prefer the
//Stuff in curly braces
code
{
}
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.
- jon
Ganymede, a GPL'ed metadirectory for UNIX
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 when this issue came up while questions were being asked.
What I'm listening to now on Pandora...
One comparison chart is at http://animal.ihug.co.nz/c++/compilers. html. 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
My usual seat in the cluetrain is at A HREF="http://pub4.ezboard.com/biwethey.ht
[Culled from a mail to PureFiction. Hope this explains more clearly
/. more often :-)
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
Han-Wen Nienhuys -- LilyPond
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. 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.
If tits were wings it'd be flying around.
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!
Read the FAQ.
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.
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.
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.
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.
.
.
.
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 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
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
It is, right here. You should read it, it's worthwhile. In particular I like the quote "Java isn't platform independent; it is a platform." :)
"Oppression and harassment is a small price to pay to live in the land of the free." -- Montgomery Burns.
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.
Jilles
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.
Jilles
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++.
Jilles
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++ in parallel.
-- v --
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?
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.
Code length is directly proportional to costs and errors. This has been a well understood engineering principle for decades.
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 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.
"There is more worth loving than we have strength to love." - Brian Jay Stanley
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.
--exa--
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.
This space for rent. All reasonable inquiries will be entertained at proprietors discretion.
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
Steven Rostedt
-- Nevermind
...for picking good questions and moderating down that old joke/fake interview about C++/job security and any questions associated with it.
Moderation worked.
The surprise isn't how often we make bad choices; the surprise is how seldom they defeat us.
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
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.
--
-=DaveHowe=-
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?
--
-=DaveHowe=-
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 <grin> - When I learnt C, C++ was still in it's new, shiny wrapper, and most of the lecturers were obscessed with Pascal anyhow
--
-=DaveHowe=-
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....
--
-=DaveHowe=-
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."
I am quite civilized, and I should be brought a beer immediately. -- Bruce Sterling
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 (see?). In fact, there's already an compiler 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.)
-jacob
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.
--
Industrial space for lease in Flatlandia.
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.
This post brought to you by your friendly neighborhood MBA.
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.
I'm trying to teach myself to set people on fire with my mind... Is it hot in here?
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
I get my kicks above the
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.
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.
More race stuff in one place,
than any one place on the net.
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.
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.
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.
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
The real mnf999 always posts as anonymous coward
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...
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?
Davo -- Free speech, free software, AND free beer.
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.
"Christianity neither is, nor ever was a part of the common law." --
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.
A response to some of your issues:
//Stuff in curly braces
:-). I personally have not missed MI.
I prefer the
code
{
}
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
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...
"There is more worth loving than we have strength to love." - Brian Jay Stanley
Here is the correct link:
Appendix E: Standard-Library Exception Safety
-- the cake is a lie
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
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. Once this has reached maturity, good templatized container classes can't be far behind.
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.
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
Vidi, Vici, Veni
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."
send all spam to theotherwhitemeat@ropine.com
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.
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 :)
--- Hot Shot City is particularly good.
(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.
Each to his own.
- ------------------
- ------------------
... }
...
- ------------------
- ------------------
- ------------------ - ------------------ - ------------------
- ------------------
- ------------------
e sirable() { returns true; }
- ------------------
- ------------------ - ------------------
...er... DDD
- ------------------
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.LongFunctionNamesD
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
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...
http://rareformnewmedia.com/
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.
LILO boot: linux init=/usr/bin/emacs
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.
Han-Wen Nienhuys -- LilyPond