|
Home | Switchboard | Unix Administration | Red Hat | TCP/IP Networks | Neoliberalism | Toxic Managers |
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and bastardization of classic Unix |
"C makes it easy to shoot yourself in the foot. C++ makes it harder, but when you do, it blows away your whole leg." - Bjarne Stroustrup The most difficult work of programmers, and also the most rewarding, is not writing programs but rather designing abstractions.
Peter Van Roy
and Seif Haridi: |
|
Object oriented programming was invented in 1969 by Dr. Kristen Nygaard of Norway. He was trying to create a simulation model of the movement of ships passing through Norwegian fjord (a long narrow arm of the sea bordered by steep cliffs). Simulation programs usually does not separate data from the procedures and the object-oriented approach is rather natural for simulation. Natural objects can be represented by a variable (simulated time), a structure or a procedure(a ship). At the beginning there were special languages that simplified implementation of simulation programs using built-in mechanisms and special language constructs. Actually Dr. Kristen Nygaard was the co-author of one first specialized language for this domain called Simula, that was pretty popular (BTW Donald Knuth was the author of another early simulation language).
|
But Dr. Nygaard was the first to realize that some simulation-oriented constructs and programming tricks are useful as a general purpose programming mechanisms. That's why he decided to create a general purpose language Simula67 based on his experience with Simula. Essentially Simula 67 introduced the concept of classes into Algol, extending the concept of records (that consist exclusively of data fields) with procedures that are included in the class (member functions). This approach which allows integration of multiple procedures working with a given set of private data (namespace) similar to multientry procedures in PL/1 with slightly different syntactic sugar later was called OO programming.
Although many consider Smalltalk to be the first OO language I would say that the really the first OO-oriented language was Simula67. That means that the OO technology is 30 years old and actually is older than Unix. C++ design was greatly influenced by Simula 67.
All-in-all Simula 67 was a pretty interesting Algol extension that in addition to classes introduced into the language a very important and innovative concept of coroutines. Later this brilliant concept found its way to Modula, Icon and Python (generators) It's interesting to note that a little bit later the concept of coroutines was introduced into Unix as pipes -- probably one of the most important Unix innovations in the area of OS design. C++ inherited only one of two principal innovations introduced by Simula 67 (classes). This second innovation that stems from simulation languages in general and Simula67 specifically is absent in C++.
I can say that I do not like C++. In its design it lost simplicity and closeness to machine architecture of C and did not gain the level of scripting programming languages. I would use scripting language plus C any time instead of C++. It is difficult to program and debug language. For most problems those added complexities do not pay. So I am not surprised to see that so many major open source projects stick to C.
There are some valid reasons to use C++ over C. First of all most compilers now can compile both C and C++ so you can use both languages with the same compiler. Although many consider C++ as object oriented language (with all related to OO cult noisy and scientifically incorrect hype), the language itself does not enforce OO-style and that's a good thing. Moreover it contains some innovations that are not strictly OO-oriented. Two major among such innovations were the concepts of templates and namespaces. Namespaces permit more manageable structuring of name space and is a very important language construct of its own, related, but independent from OO.
Some OO constructs can be used non-traditionally in a pure procedural fashion. You can imitate read-only variables by using inline methods that access private variables in a class. Friends provide a decent imitation of group access to a particular subset of the name space. C++ also has lots of small improvements over C that any C programmer will be able to appreciate: strings, exceptions, more flexible O/I, being able to declare new variables anywhere, inline functions, generic programming. Funny most of them were present in PL/1 which C designers used as a prototype (PL/1 was used as a system programming language in Multics). On high end one should consider learning STL that contains a library of important algorithms.
One important advice to those who want to learn C++: you need to chose compiler wisely. Do not stick to gcc. Gcc is a good compiler, but not for novices. The quality of diagnostics leaves much to be desired. Also while analyzing the gcc source can be very educational, in the end you probably never have a compelling need to look into compiler's source code. You have at least three other choices:
Never study C++ as if it is limited to OO. OOP isn't a panacea (from the point of view of programming productivity combination of a scripting language and C, for example TCL+C or Python+C can win) and is oversold as a method of programming. Historically OO popularity was to the large extent consequence of the growth of the popularity of GUI applications, not so much by its own merits. Also catchy name is half of success in programming.
Like for a hummer everything in the world is a nail, for OO evangelists everything in the world is an object ;-). This is not true. Yes, there are cases when such a uniform vision represents a breakthrough in particular narrow area (for example Unix idea that all devices are files was a wonderful breakthrough), but you need to understand the limits of applicability to benefit from such a vision. See for example OOP Criticism (The emperor has no clothes!).
In his recent interview on Slashdot Bjarne Stroustrup wrote about OO blah-blah-blah:
"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."
At the same time object orientation was and is used as a most favorite method to kill interest in programming, as a method of abuse college students by instructors who no longer care for students ;-). Like any cult OO religion with its semi-ignorant zealots is a really bad thing. And it's really unfortunate if such a zealot is your college instructor, especially if he/she for some stupid reasons teaches OO in the first programming language course :-(. After all the main idea is to learn programming, not YASLF (Yet Another Stupid Language Fad). The best thing than can happen to you in this case is when the course actually contains C subset of the language in the first chapters like college courses based on A First Book of C++ From Here to There (a very good book). Or when the teacher (and the textbook that he/she selected) tries to teach a C++ as a better C like in C++ Primer Plus.
BTW OO religious mentality (or programming fashion, if you wish, because in programming languages fashion rules, remember all this noise about Java in 1997-1999; in reatly Java turned into a new Cobol. that's say all about the quality of the language) is now extended to another area, patterns. Some of the ideas that are presented as an ultimate achievement of this movement are valid (and actually pretty old), but they are mostly drown in the OO blah-blah-blah. For those who are over-fascinated with the this fad I strongly recommend to read Patterns of Software - Tales from the Software Community" by Richard Gabriel, one of the founding fathers of the "patterns movement". His opinion? Patterns don't gain you much, unless you're one of the snake-oil salesmen profiting by selling the idea. Here is another relevant quote from Bjarne Stroustrup (see also his famous newsgroup posting):
Rule: "Don't Try To Force People"
Programmers are smart people. They are engaged in challenging tasks and need all the help they can get from a programming language as well as from other supporting tools and techniques. Trying to seriously constrain programmers to do "only what is right" is inherently wrongheaded and will fail. Programmers will find a way around rules and restrictions they find unacceptable. The language should support a range of reasonable design and programming styles rather than try to force people into adopting a single notion.
This does not imply that all ways of programming are equally good or that C++ should try to support every kind of programming style. [...] However, moralizing over how to use the features is kept to a minimum, language mechanisms are as far as possible kept policy free, and no feature is added to or subtracted from C++ exclusively to prevent a coherent style of programming.
I am well aware that not everyone appreciates choice and variety. However, people who prefer a more restrictive environment can impose one through style rules in C++ or choose a language designed to provide the programmer with a smaller set of alternatives.
-- "The Design and Evolution of C++", page 113
There is a difference between writing 50-line programs, 3,000 line, and 30,000 lines programs... designed, developed, documented, tested, and integrated... and all along, As program grow larger writer is confronted with more software engineering problems than programming problems. For example, the problem of namespaces inevitably arises in large programming projects and here C++ has a definite an edge over C. Templates also can help in large projects.
Let me try to sum my view on C++ in the following way -- programming is cranking out a solution to a problem in the most efficient way. But premature paradigm adoption (for example, OO) like a premature optimization is the source of major problems. The programming methodology should be tuned to the problem in hand not vise-versa.
Premature paradigm adoption (for example, OO) like a premature optimization is the source of major problems. The programming methodology should be tuned to the problem in hand not vise-versa |
See OOP Criticism for more details.
OOP became popular primarily because of GUI interfaces. In fact, many non-programmers think that "Object" in OOP means a screen object such as a button, icon, or listbox. They often talk about drag-and-drop "objects". GUI's sold products. Anything associated with GUI's was sure to get market and sales brochure attention, regardless of whether this association was accurate or not. I have even seen salary surveys from respected survey companies that have a programming classification called "GUI/OOP Programming".
Screen objects can correspond closely with OOP objects, making them allegedly easier to manipulate in a program. We do not disagree that OOP works fairly well for GUI's, but it is now being sold as the solve-all and be-all of programming.
Some argue that OOP is still important even if not dealing directly with GUI's. In our opinion, much of the hype about OOP is faddish. OOP in itself does NOT allow programs to do things that they could not do before. OOP is more of a program organizational philosophy rather than a set of new external solutions or operations.
In his old Usenix paper Objecting To Objects Stephen C. Johnson wrote
Object-oriented programming (OOP) is an ancient (25-year-old) technology, now being pushed as the answer to all the world's programming ills. While not denying that there are advantages to OOP, I argue that it is being oversold. In particular, OOP gives little support to GUI and network support, some of the biggest software problems we face today. It is difficult to constrain relationships between objects (something SmallTalk did better than C++). Fundamentally, object reuse has much more to do with the underlying models being supported than with the object-ness of the programming language. Object-oriented languages tend to burn CPU cycles, both at compile and execution time, out of proportion to the benefits they provide. In summary, the goods things about OOP are often the information hiding and consistent underlying models which derive from clean thoughts, not linguistic cliches.
Actually if we talk about efficiency the rule is that 80% of time are spend in 20% of code and if you really care about efficiency those 20% of code should be written in a simpler more efficient language -- for C++ than means C , for C it means assembler. That's why the bible of system programmers The Art of Computer Programming by Donalds Knuth is still as important as it was 30 years ago.
As problem complexity increases, C++ become more and more viable solution although I would prefer with the combination of TCL and C, or Python and C++ to plain-vanilla C++ in many practical situations. Software engineering is about developing the solution to a complex problem in a manner that others can understand and maintain; that is not only well documented but preferably self-documented.
C+= in many ways is difficult for maintenance language, far more difficult then scripting language. And not only because it is verbose, but also because modern computers make heap allocation of variables mainstream. In many cases C++ as a higher level language (especially with STL) is good enough and is a viable choice (the quality of C++ compilers is pretty decent these days). But again the main word here is choice; if I can produce a solution in TCL+C or Python and C++ that takes at least 50% less lines of code in comparison with plain vanilla C++ I will stick with it unless there are other important considerations that can move me to C++.
At the same time C++ is less restrictive, support multiparadigm programming and can be 10 times (or more) efficient than Java :-). Like OO, Java is definitely oversold and does not provide flexibility and efficiency of the server side in comparison with C++ (at least with today's implementations of Java). It is a new Cobol (actually while Cobol was really designed with view on business application, Java was designed for imbedded systems programming). And it is as fascinating as Cobol. End of story. If you have nice hardware and not so many visitors that's OK. If this is not the case, C++ wins. And to add insult to injury C++ debuggers are generally far better then Java debuggers :-)
Dr. Nikolai Bezroukov
|
Switchboard | ||||
Latest | |||||
Past week | |||||
Past month |
To preserve bandwidth for humans as opposed to robots News now are moved in a separate subdirectory. As with any move some of them were lost... Sorry for any inconvenience.
2004 | 2003 | 2002 | 2001 | 2000 |
Jun 09, 2013 | YouTube
Nick Geoghegan
James Maguire's article raises some interesting questions as to why teaching Java to first year CS / IT students is a bad idea. The article mentions both Ada and Pascal neither of which really "took off" outside of the States, with the former being used mainly by contractors of the US Dept. of Defense.
This is my own, personal, extension to the article which I agree with and why first year students should be taught C in first year. I'm biased though, I learned C as my first language and extensively use C or C++ in projects.
Java is a very high level language that has interesting features that make it easier for programmers. The two main points, that I like about Java, are libraries (although libraries exist for C / C++ ) and memory management.
LibrariesLibraries are fantastic. They offer an API and abstract a metric fuck tonne of work that a programmer doesn't care about. I don't care how the library works inside, just that I have a way of putting in input and getting expected output (see my post on abstraction). I've extensively used libraries, even this week, for audio codec decoding. Libraries mean not reinventing the wheel and reusing code (something students are discouraged from doing, as it's plagiarism, yet in the real world you are rewarded). Again, starting with C means that you appreciate the libraries more.
Memory ManagementManaging your programs memory manually is a pain in the hole. We all know this after spending countless hours finding memory leaks in our programs. Java's inbuilt memory management tool is great it saves me from having to do it. However, if I had have learned Java first, I would assume (for a short amount of time) that all languages managed memory for you or that all languages were shite compared to Java because they don't manage memory for you. Going from a "lesser" language like C to Java makes you appreciate the memory manager
What's so great about C?
In the context of a first language to teach students, C is perfect. C is
- Relatively simple
- Procedural
- Lacks OOP features, which confuse freshers
- Low level
- Fast
- Imperative
- Weakly typed
- Easy to get bugs
Java is a complex language that will spoil a first year student. However, as noted, CS / IT courses need to keep student retention rates high. As an example, my first year class was about 60 people, final year was 8. There are ways to keep students, possibly with other, easier, languages in the second semester of first year so that students don't hate the subject when choosing the next years subject post exams.
Conversely, I could say that you should teach Java in first year and expand on more difficult languages like C or assembler (which should be taught side by side, in my mind) later down the line keeping retention high in the initial years, and drilling down with each successive semester to more systems level programming.
There's a time and place for Java, which I believe is third year or final year. This will keep Java fresh in the students mind while they are going job hunting after leaving the bosom of academia. This will give them a good head start, as most companies are Java houses in Ireland.
nickgeoghegan.net
Filed in Programming No Comments
A few things can confuse programming students, or new people to programming. One of these is abstraction.Wikipedia says:
In computer science, abstraction is the process by which data and programs are defined with a representation similar to its meaning (semantics), while hiding away the implementation details. Abstraction tries to reduce and factor out details so that the programmer can focus on a few concepts at a time. A system can have several abstraction layers whereby different meanings and amounts of detail are exposed to the programmer. For example, low-level abstraction layers expose details of the hardware where the program is run, while high-level layers deal with the business logic of the program.
That might be a bit too wordy for some people, and not at all clear. Here's my analogy of abstraction.
Abstraction is like a car
A car has a few features that makes it unique.
- A steering wheel
- Accelerator
- Brake
- Clutch
- Transmission (Automatic or Manual)
If someone can drive a Manual transmission car, they can drive any Manual transmission car. Automatic drivers, sadly, cannot drive a Manual transmission drivers without "relearing" the car. That is an aside, we'll assume that all cars are Manual transmission cars as is the case in Ireland for most cars.
Since I can drive my car, which is a Mitsubishi Pajero, that means that I can drive your car a Honda Civic, Toyota Yaris, Volkswagen Passat.
All I need to know, in order to drive a car any car is how to use the breaks, accelerator, steering wheel, clutch and transmission. Since I already know this in my car, I can abstract away your car and it's controls.
I do not need to know the inner workings of your car in order to drive it, just the controls. I don't need to know how exactly the breaks work in your car, only that they work. I don't need to know, that your car has a turbo charger, only that when I push the accelerator, the car moves. I also don't need to know the exact revs that I should gear up or gear down (although that would be better on the engine!)
Virtually all controls are the same. Standardization means that the clutch, break and accelerator are all in the same place, regardless of the car. This means that I do not need to relearn how a car works. To me, a car is just a car, and is interchangeable with any other car.
Abstraction means not caring
As a programmer, or someone using a third party API (for example), abstraction means not caring how the inner workings of some function works Linked list data structure, variable names inside the function, the sorting algorithm used, etc just that I have a standard (preferable unchanging) interface to do whatever I need to do.
Abstraction can be taught of as a black box. For input, you get output. That shouldn't be the case, but often is. We need abstraction so that, as a programmer, we can concentrate on other aspects of the program this is the corner-stone for large scale, multi developer, software projects.
This article is intended to help C & C++ programmers understand the essentials of what the linker does. I've explained this to a number of colleagues over the years, so I decided it was time to write it down so that it's more widely available (and so that I don't have to explain it again). [Updated March 2009 to include more information on the pecularities of linking on Windows, plus some clarification on the one definition rule.]
by dkf (304284) <[email protected]> on Saturday December 06, @07:08PM (#26016101) HomepageC/C++ are the languages you'd want to go for. They can do *everything*, have great support, are fast etc.
Let's be honest here. C and C++ are very fast indeed if you use them well (very little can touch them; most other languages are actually implemented in terms of them) but they're also very easy to use really badly. They're genuine professional power tools: they'll do what you ask them to really quickly, even if that is just to spin on the spot chopping peoples' legs off. Care required!
If you use a higher-level language (I prefer Tcl, but you might prefer Python, Perl, Ruby, Lua, Rexx, awk, bash, etc. - the list is huge) then you probably won't go as fast. But unless you're very good at C/C++ you'll go acceptably fast at a much earlier calendar date. It's just easier for most people to be productive in higher-level languages. Well, unless you're doing something where you have to be incredibly close to the metal like a device driver, but even then it's best to keep the amount of low-level code small and to try to get to use high-level things as soon as you can.
One technique that is used quite a bit, especially by really experienced developers, is to split the program up into components that are then glued together. You can then write the components in a low-level language if necessary, but use the far superior gluing capabilities of a high-level language effectively. I know many people are very productive doing this.
About: Sunifdef is a command line tool for eliminating superfluous preprocessor clutter from C and C++ source files. It is a more powerful successor to the FreeBSD 'unifdef' tool. Sunifdef is most useful to developers of constantly evolving products with large code bases, where preprocessor conditionals are used to configure the feature sets, APIs or implementations of different releases. In these environments, the code base steadily accumulates #ifdef-pollution as transient configuration options become obsolete. Sunifdef can largely automate the recurrent task of purging redundant #if logic from the code.
Changes: Six bugs are fixed in this release. Five of these fixes tackle longstanding defects of sunifdef's parsing and evaluation of integer constants, a niche that has received little scrutiny since the tool branched from unifdef. This version provides robust parsing of hex, decimal, and octal numerals and arithmetic on them. However, sunifdef still evaluates all integer constants as ints and performs signed integer arithmetic upon them. This falls short of emulating the C preprocessor's arithmetic in limit cases, which is an unfixed defect.
August 20, 2007 | www.artima.com
Summary
Readily available frameworks and APIs can make developers very productive. However, they can also limit developers' imagination, explains Overstock.com principal software engineer Chris Maki in this brief audio interview with Artima.
One of Java's key strengths today is its multitude of APIs and frameworks, addressing a wide range of problem domains. Such APIs and frameworks provide ready-made answers to many programming problems. Indeed, programming in Java today is to a great extent an exercise in learning to identify and use APIs and frameworks suited to a problem area.
Using readily available APIs and frameworks can keep a developer at a fairly high level of abstraction: Part of a Java developer's productivity comes from not having to reinvent the wheel with every project-instead, a developer can apply high-level frameworks to a set of similar projects and problems, expecting generally high-quality results.
While productivity is very important in a developer's work, so is originality and innovation. In a conversation at JavaOne earlier this year, Chris Maki, a principal software engineer at Overstock.com and leader of the Utah Java Users Group, told us that the frameworks and APIs that make us so productive also impose upon us their design decisions and their solutions to problems, sometimes leaving little room for innovation and originality:
When I first started as a software engineer... we used to think that anything you could think of, that anything you could conceive of, was possible with software, and that the sky was the limit. And we tried to do that. Today, it seems like we look at the Java APIs and the different packages, and say, "Well, this is all we can do. This is what the APIs tell us."
Back in those days, we were doing more typical client-server type applications. We would have a database, and most of the logic was in what we would call a fat client today. In the graphical or presentation layer, we would [use] animations... One of the applications I was working on was a pipeline application, which doesn't sound very sexy or interesting, yet as data moved through the pipeline, we used animations to show pictures of the different places the product would go, have [part of the UI] fade in and fade out... to visualize this movement of data...
If I was going to do that in Java [today], it would seem to me like a daunting task, given the complexities of some of the Swing APIs. I know that they made a lot of improvements, but when I sit down to do an app today, I don't think [that] whatever I can think of I'm going to do. I typically think the APIs and the design patterns tell me I've got to do this [or that]. While we made a lot of improvements by having cross-platform code, and write once, deploy anywhere kind of things, we've also limited our thinking.
Chris Maki, principal software engineer at Overstock.com, talks about how frameworks and APIs can limit developers' imaginations. (3 minutes 10 seconds) To what extent do you think there is a role for the in-the-trenches enterprise developer to devise innovative and out-of-the-box solutions? In your projects, how do you mitigate the need for productivity that comes from following the prescriptions of a high-level framework, and the desire to come up with original and sometimes surprising, solutions?
freshmeat.net
SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is primarily used with common scripting languages such as Perl, PHP, Python, Tcl/Tk, and Ruby, however the list of supported languages also includes non-scripting languages such as C#, Common Lisp (CLISP, Allegro CL, UFFI), Java, Modula-3, OCAML, and R. Also several interpreted and compiled Scheme implementations (Guile, MzScheme, Chicken) are supported. SWIG is most commonly used to create high-level interpreted or compiled programming environments, user interfaces, and as a tool for testing and prototyping C/C++ software. SWIG can also export its parse tree in the form of XML and Lisp s-expressions.
Release focus: Minor feature enhancements
Changes:
shared_ptr support was added for Java and C#. STL support for Ruby was enhanced. Windows support for R was added. A long-standing memory leak in the PHP module was fixed. Numerous fixes and minor enhancements were made for Allegrocl, C#, cffi, Chicken, Guile, Java, Lua, Ocaml, Perl, PHP, Python, Ruby, and Tcl. Warning support was improved.
The author discusses how the use of generic programming in C++ can lead to conflicts with object-oriented design principles. He demonstrates how a technique known as type erasure can often be used to resolve these conflicts. An in-depth example is presented:any_iterator
, a type-safe, heterogeneous C++ iterator.In his glossary of terms[1], Bjarne Stroustrup has described the C++ programming language that he created as "a general-purpose programming language [...] that supports procedural programming, data abstraction, object-oriented programming, and generic programming." The fact that C++ supports these different programming paradigms makes it unique-and uniquely powerful-among today's programming languages. On the other hand, it should not come as a surprise that the close coexistence of such vastly different paradigms can cause considerable friction, especially in large software systems.
In this article, I will focus on the tension that can occur when object-oriented programming (classes, objects, and runtime polymorphism come to mind) meets generic programming (algorithms, templates, and compile time polymorphism come to mind).
The article consists of two parts. In the first part, I will demonstrate how the coexistence of OO and generic programming can cause serious friction in real-life software engineering. I will then explain how a technique known as type erasure can be used to alleviate these problems.
The second part explains how type erasure can be implemented in C++. Specifically, I will elaborate on an example used in the first part, namely, C++ iterator type erasure. I will discuss the design and implementation of a class template[2]
any_iterator
that provides type erasure for C++ iterators.The Trouble with Object-Oriented and Generic Programming
A Little Trivia Quiz
Let us start with a little trivia quiz. Who said the following things about object-oriented programming?
- "I find OOP technically unsound."
- "I find OOP philosophically unsound."
- "I find OOP methodologically wrong."
- "I have yet to see an interesting piece of code that comes from these OO people."
- "I think that object orientedness is almost as much of a hoax as artificial intelligence."
All the quotes above are from an interview with Alexander Stepanov[3], the inventor of the STL and elder statesman of generic programming. As a practicing software engineer who works on large commercial software projects, I know better than to hold such a negative view of OO programming. But when someone like Alexander Stepanov says such a thing, then I don't think it should be taken lightly.
My experience as a software engineer in the trenches has taught me that there is much more tension, if not contradiction or incompatibility, between OO programming and generic programming than many people care to admit. It is easy to dismiss Alexander Stepanov's rejection of OO programming as extreme and unrealistic. It is much harder to make the OO and generic programming paradigms coexist and cooperate in real-life software engineering.
In the next three sections, I will illustrate the problem with an example from the real world, and I will suggest a less radical remedy than to disavow OO programming as a tool in software design altogether.
Hello, world! Today, I (Stephan T. Lavavej, library dev) would like to present one question and one Orcas bugfix.
First, the question: What is the future of C++? Or, phrased crudely, does C++ have a future? Will it grow and evolve, with programmers using it in new application domains and finding ways to use it more effectively? Or will it stagnate, with programmers using it in fewer and fewer application domains until nothing new is being invented with it and it enters "maintenance mode" forever? After C++'s explosive growth over nearly the last three decades, what is going to come next?
This question has a finite horizon. No language can possibly be eternal, right? (Although C is certainly making a good run for it.) I don't expect C++ to be vibrant in 2107, or even 2057. 50 years is an almost incomprehensible span of time in the computer industry; the transistor itself is turning 60 years old this year. So when I ask, "what is the future of C++?", I'm really asking about the next 10, 20, and 30 years.
Here's how I see it. First, consider C++'s past. As it happens, Bjarne Stroustrup recently released an excellent paper covering C++'s recent history, "Evolving a language in and for the real world: C++ 1991-2006", at http://research.att.com/~bs/hopl-almost-final.pdf . There's also a wonderful 1995 interview with Alexander Stepanov at http://stepanovpapers.com/drdobbs-interview.html which explains C++'s machine model.
C++'s machine model has a relentless focus on performance, for several reasons. Being derived from C, which was "fat free", is one reason - in the realm of performance, C++ has never had to lose weight. It's just had to avoid gaining weight. Additions to C++ have always been structured in such a way as to be implementable in a maximally efficient manner, and to avoid imposing costs on programmers who don't ask for them. (As the Technical Report on C++ Performance, now publicly available at http://standards.iso.org/ittf/PubliclyAvailableStandards/c043351_ISO_IEC_TR_18015_2006(E).zip , explains, exception handling can be implemented with the "table" approach, which imposes minimal run-time overhead on code that doesn't actually throw. VC uses the "code" approach on x86 because of historical reasons, although it uses the "table" approach on x64 and IA-64.) Historically, C++ ran on very small and slow machines that couldn't bear any unnecessary costs. And now, C++ is used to tackle huge problems where performance is critical, so unnecessary costs are still unthinkable!
Aside from the elevator controllers and supercomputers, does performance still matter for ordinary desktops and servers? Oh yes. Processors have finally hit a brick wall, as our Herb Sutter explained in 2005 at http://gotw.ca/publications/concurrency-ddj.htm . The hardware people, who do magical things with silicon, have encountered engineering limitations that have prevented consumer processors from steadily rising in frequency as they have since the beginning of time. Although our processors aren't getting any slower, they're also not getting massively faster anymore (at least, barring some incredible breakthrough). And anyways, there isn't plenty of room at the bottom anymore. Our circuits are incredibly close to the atomic level, and atoms aren't getting any smaller. The engineering limit to frequency has simply arrived before the physical limit to circuitry. Caches will continue to get larger for the foreseeable future, which is nice, but having a cache that's twice as large isn't as nice as running everything at twice the frequency.
As programmers, we are faced with a future that looks radically different from what we're used to: the processors we have today are about as fast as we will ever have. The computer industry undergoes constant change, of course, but we rather liked the kind of change that made our programs run twice as fast every couple of years with no extra work on our part.
Undaunted, the hardware engineers have begun putting multiple cores in each processor, which is actually increasing overall performance quite nicely. (I'd sure like to have a quad-core machine at work!) But not everything is as embarrassingly parallel as compiling. Single-core performance still matters. And the problems that we, as programmers, are asked to solve are getting bigger every year, as they always have.
Therefore, I say that C++ is uniquely positioned to weather this performance storm. Other languages will continue to find uses in application domains that aren't performance-critical, or that are embarrassingly parallel. But whenever the speed at which an individual core crunches stuff matters, C++ will be there. (For example, 3D games. When Halo Infinity is released in 2027 - and yes, I totally just made that up - I fully expect it to be written in C++.)
Among C++0x's biggest core language changes will be variadic templates, concepts, and rvalue references. The first two will make writing templates a lot more fun. That's great, because templates are a powerful way to produce highly efficient code. And the third will address one of the flabbiest areas in C++03 - its tendency to make copies of values. (Things that have value semantics are great - unnecessary copies aren't.) By eliminating unnecessary copies through "move semantics", rvalue references will make value-heavy code, like any code that uses the STL, significantly faster. The future is bright!
Dec 14, 2006 (InfoWorld) Joel Spolsky is one of our most celebrated pundits on the practice of software development, and he's full of terrific insight. In a recent blog post, he decries the fallacy of "Lego programming" -- the all-too-common assumption that sophisticated new tools will make writing applications as easy as snapping together children's toys. It simply isn't so, he says -- despite the fact that people have been claiming it for decades -- because the most important work in software development happens before a single line of code is written.
By way of support, Spolsky reminds us of a quote from the most celebrated pundit of an earlier generation of developers. In his 1987 essay "No Silver Bullet," Frederick P. Brooks wrote, "The essence of a software entity is a construct of interlocking concepts ... I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation ... If this is true, building software will always be hard. There is inherently no silver bullet."
As Spolsky points out, in the 20 years since Brooks wrote "No Silver Bullet," countless products have reached the market heralded as the silver bullet for effortless software development. Similarly, in the 30 years since Brooks published " The Mythical Man-Month" -- in which, among other things, he debunks the fallacy that if one programmer can do a job in ten months, ten programmers can do the same job in one month -- product managers have continued to buy into various methodologies and tricks that claim to make running software projects as easy as stacking Lego bricks.
Don't you believe it. If, as Brooks wrote, the hard part of software development is the initial design, then no amount of radical workflows or agile development methods will get a struggling project out the door, any more than the latest GUI rapid-development toolkit will.
And neither will open source. Too often, commercial software companies decide to turn over their orphaned software to "the community" -- if such a thing exists -- in the naive belief that open source will be a miracle cure to get a flagging project back on track. This is just another fallacy, as history demonstrates.
In 1998, Netscape released the source code to its Mozilla browser to the public to much fanfare, but only lukewarm response from developers. As it turned out, the Mozilla source was much too complex and of too poor quality for developers outside Netscape to understand it. As Jamie Zawinski recounts, the resulting decision to rewrite the browser's rendering engine from scratch derailed the project anywhere from six to ten months.
This is a classic example of the fallacy of the mythical man-month. The problem with the Mozilla code was poor design, not lack of an able workforce. Throwing more bodies at the project didn't necessarily help; it may have even hindered it. And while implementing a community development process may have allowed Netscape to sidestep its own internal management problems, it was certainly no silver bullet for success.
The key to developing good software the first time around is doing the hard work at the beginning: good design, and rigorous testing of that design. Fail that, and you've got no choice but to take the hard road. As Brooks observed all those years ago, successful software will never be easy. No amount of open source process will change that, and to think otherwise is just more Lego-programming nonsense.
About 10 months ago, I was writing a library. As I was writing it, I started to look at the whole issue of notifying the caller of errors. In typical fashion, I tried to optimize the error handling problem rather than just do the right thing, and just use error codes. I did a ton of research. Here is a current list of links and articles on the subject.
Getting Started
To get you started here are some good starting points. They both received a lot of attention on the internet.
A colorful post by Damien Katz.
A nice opinion piece that is pro-error codes by the famous Joel of Joel on Software.
Read my original post with excellent comments by Daniel Lyons, Paul Clegg, and Neville of the North.
Nutshell
The default and standard way of handling errors since the begining is to just use error codes with some convention of noticing them. For example, you could document the error condition with an api and then set a global variable for the actual code. It is up to the programmer calling the function to notice the error and do the right thing.
This is the technique used by operating systems and most libraries. Historically, these systems have never been consistent or compatable with other conventions. The most evolved system for this would probably be the Microsoft COM system. All functions return an HRESULT, which is essentially an error code.
The next system was the 'exception-handling' system. In this system errors cannot be ingored. Exception handlers are declared, optionally, at a given scope. If an exception is thrown (ie an error has occurred), handlers are searched up the stack until a matching handler is found.
IMHO, the exception system isn't used properly in 90% of the cases. There is a fine balance between a soft error and something exceptional. The syntax also tends to get in the way for even the simplest of errors. I agree that there should be errors that are not ignored, but there has to be a better way.
So, old skoolers are 'we use error codes, and we like them, dammit - aka, super disciplined programming, usually for real-time, embedded and smaller systems.
The new schoolers are, 'you have to be kidding about error-codes, use exceptions' - aks, yeah, we use exceptions, that is what the language gives us and btw, no, we don't mind typing on our keyboards a lot
Somehow, there has to be a better way. Maybe it will be system or application, specific.
Moving On - Old / New Ideas
If you don't mind it being a C++ article, here is an amazing one from Andrei Alexandrescu and Petru Marginean. (Andrei is widely known for his great work on Policy Based design with C++, which is excellent) The artcle is well written and practical. In fact, the idea was so good, the language 'D' made it part of the language.
Here is an example:
void User::AddFriend(User& newFriend) { friends_.push_back(&newFriend); try { pDB_->AddFriend(GetName(), newFriend.GetName()); } catch (...) { friends_.pop_back(); throw; } }
10 lines, and this is for the super-simple example.
void User::AddFriend(User& newFriend) { friends_.push_back(&newFriend); ScopeGuard guard = MakeObjGuard(friends_, &UserCont::pop_back); pDB_->AddFriend(GetName(), newFriend.GetName()); guard.Dismiss(); }
In D it would look even cleaner:
void User::AddFriend(User& newFriend) { friends_.push_back(&newFriend); scope(failure) friends_.pop_back(); pDB_->AddFriend(GetName(), newFriend.GetName()); }
IMHO, I think exception handling will move more towards systems like this. Higher level, simpler and cleaner.
Other interesting systems are the ones developed for Common Lisp, Erlang, and Smalltalk. I'm sure Haskell has something to say about this as well.
The Common Lisp and Smalltalk ones are similar. Instead of forcing a mechanism like most exception handlers. These systems give the exception 'catcher' the choice of retry'ing or doing something different at the point of the exception. Very powerful.
Speaking of smalltalk, here is an excellent article called Subsystem Exception Handling in Smalltalk. I highly recommend it.
My Recomendation
If you are building a library, use error codes. Error codes are much easier to turn into exceptions by the language wrapper that will eventually be built on top.
When programming, don't get trapped into think about the little picture. A lot of these errors are just pawns in the grand scheme of assuring that you have all of your resources in place before you begin your task at hand. If you present your code in that manner, it will be much easier to understand for all parties.
More Links
Error Codes vs. Exceptions by Damien Katz.
opinion piece that is pro-error codes by the famous Joel of Joel on Software.
Read my original post with excellent comments by Daniel Lyons, Paul Clegg, and Neville of the North.
D Language - Exception Safe Programming
Subsystem Exception Handling in Smalltalk - nice section on history as well
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
A nice long thread on comp.lang.c++.moderated
*Slightly Wacky, But Neat *
http://www.halfbakery.com/idea/C20exception20handling_20macros http://www.nicemice.net/cexcept/ http://home.rochester.rr.com/bigbyofrocny/GEF/ http://www.on-time.com/ddj0011.htm
doxygen 1.5.1
by Dimitri van Heesch - Sun, Oct 29th 2006 11:00 PDTAbout: Doxygen is a cross-platform, JavaDoc-like documentation system for C++, C, Objective-C, C#, Java, IDL, Python, and PHP. Doxygen can be used to generate an on-line class browser (in HTML) and/or an off-line reference manual (in LaTeX or RTF) from a set of source files. Doxygen can also be configured to extract the code-structure from undocumented source files. This includes dependency graphs, class diagrams and hyperlinked source code. This type of information can be very useful to quickly find your way in large source distributions.
Changes: This release fixes a number of bugs that could cause it to crash under certain conditions or produce invalid output.
I am not saying OOP is useless, per se; many are just frustrated with the fact that OOP has slowed or even reversed programming progress in other areas. I have debated OO fans that appear ignorant to some nifty techniques available in old-fashioned procedural programming. Often times someone will compare C to C++ and conclude that the differences are paradigm differences.
... ... ...
OOP is the greatest boon for those who like to write bloated code. I am not saying that all OOP code is bloated. But, something or someone is encouraging the practice of taking the most amount of code to do the fewest things. Further, OOP has added new ways to write bloated code that procedural has a hard time competing with. Hypothetical example for adding two numbers:
... ... ...
OOP sometimes takes credit for ideas that are not necessarily part of OOP. For example, some criticize the variable scoping rules of procedural languages, saying that OOP improved it. However, some procedural languages like Pascal already allowed multiple levels of variable and procedure scoping before OOP became a mainstream fad.
Having variable parameter types and quantities has been part of many interpreted procedural languages a good time before OOP became a mainstream fad. For example, in XBase you can use the Type() function to query a parameter type. (It lacked formality, but it was there.)
Summary
It is hard to summarize such a complex, involved topic; but here goes an attempt anyhow. Most problems with OOP can be summed up in a handful of general principles.
The real world does not change in a hierarchical way for the most part. You can force a hierarchical classification onto many things, but you cannot force change requests to cleanly fit your hierarchy. Just because a structure is conceptually simple does not necessarily mean it is also change-friendly.
There are multiple orthogonal aspect grouping candidates and the ones favored by OOP are probably not the best in many or most cases. OO literature is famous for only showing changes that benefit the aspects favored by OO. In the real world, changes come in many aspects, not just those favored or emphasized by OO. Encapsulating by just a single dimension is often a can of worms.
OOP's granularity of grouping and separation is often larger than actual changes and variations. OOP's alleged solutions to this, such as micro-methods and micro-classes, create code management headaches and other problems.
OOP designs tend to reinvent the database in application code. In particular, OO generally reinvents navigational databases, which were generally rejected in the 1970's and replaced by relational techniques. It is my opinion that relational theory is generally superior to navigational theory. It can provide more structure, cleaner queries, and automated optimization. Plus, the usage of databases allows multiple tools and languages to share and use data without writing explicit access methods for each new request.
There is no decent, objective, and open evidence that OOP is better. It may just all be subjective or domain-specific. Software engineering is sorely lacking good metrics.
There is a large lack of consistency in OO business design methodologies. Procedural/relational approaches tend to be more consistent in my experience. (Group code by task, and use database to model noun structures and relations.)
Many of the past sins that OOP is trying to fix are people and management issues (incentives, training, etc.), and not the fault of the paradigms involved. Until true A.I. comes along, no paradigm will force good code. If anything, OOP simply offers more ways to screw up.
OOP Myths Debunked:
- Myth: OOP is a proven general-purpose technique
- Myth: OOP models the real world better
- Myth: OOP makes programming more visual
- Myth: OOP makes programming easier and faster
- Myth: OOP eliminates the "complexity" of "case" or "switch" statements
- Myth: OOP reduces the number of places that require changing
- Myth: OOP increases reuse (recycling of code)
- Myth: Most things fit nicely into hierarchical taxonomies
- Myth: Sub-typing is a stable way to model differences
- Myth: Self-handling nouns are more useful than self-handling verbs
- Myth: Most operations have one natural "primary noun"
- Myth: OOP does automatic garbage-collection better
- Myth: Procedural cannot do components well
- Myth: OO databases can better store large, multimedia data
- Myth: OODBMS are overall faster than RDBMS
- Myth: OOP better hides persistence mechanisms
- Myth: C and Pascal are the best procedural can get
- Myth: SQL is the best relational language
- Myth: OOP would have prevented more Y2K problems
- Myth: OOP "does patterns" better
- Myth: Only OOP can "protect data"
- Myth: Implementation changes significantly more often than interfaces
- Myth: Procedural/Relational ties field types and sizes to the code more
- Myth: Procedural cannot extend compiled portions very well
- Myth: No procedural language can re-compile at the routine level
- Myth: Procedural/Relational programs cannot "factor" as well
- Myth: OOP models human thought better (Which human?)
- Myth: OOP is more "modular"
- Myth: OOP divides up work better
- Myth: OOP "hides complexity" better
- Myth: OOP better models spoken language
- Myth: OOP is "better abstraction"
- Myth: OOP reduces "coupling"
- Myth: OOP does multi-tasking better
- Myth: OOP scales better
- Myth: OOP is more "event driven"
- Myth: Most programmers prefer OOP
- Myth: OOP manages behavior better
Google matched content |
Generally search engines are the only way to keep up in this area. So links below are just a small sample that I have found useful.
Bookshelf
Magazines:
See also ../Links/links2magazines.shtml
TDDI42 Data structures, algorithms, and C++
COP3530 Data Structures in C++ Copyright (c) 1997, 1998, 1999, 2000, Mark Allen Weiss.
Joseph Bergin - Home Page -- Karel++
-- nice idea, horrible implementation. Hell is paved with good intentions.
See also C++ Resource Directory: Links to C++ info, courses and resources on a variety of compilers and extensions to the C++ language. For OO terminology see Glossary of Object-Oriented Terminology for Business and www.webreference.com
Microsoft Visual Studio 6.0 Service Pack 5 - Download
Namespaces:
Scoping and visibility rules:
**** TutorialIndex.com C and C++ Pointers and Memory -- nice collection of links
***** Tourist Guide to Pointer Traps
Data Abstraction and Structures Using C++ Headington and Riley Chapter 7 Pointers and Dynamic Data
c, c++, c__,Pointers Tutorial.
C++ Tutorial 3.3, Pointers. -- good tutorial
apcmag: Programming July 99: C++ pointers (Jun 30, 1999)
Pointer Variables --slide show here is another one Learning C++
Humor
Book reviews
STLport made strategic partnership with the Scientron corporation, a gateway for American high-tech corporations to the resources of Russian Academy of Sciences.
Borland
ships STLport Library with C++ Builder 6, as the default ANSI/ISO Standard Library.
Reference
A lot of things depend on the quality of complier, see for example Coyote Gulch Productions - Benchmarking Intel C++ against GNU gcc on Linux Generally Intel compiler is a better optimizing compilers that any of the competitors.
C++ Data Display Debugger (RPI - ACM)
Program Styles & Debugging Tools in Visual C++
Visual Studio
Unix
Mistakes the compiler doesn't catch (the hardest problems to solve sometimes)
cin/cout
outputs wrong number of items or just completely skips some if,
do, while, for
, etc. do not take a semicolon at the end of the line)! switch/case
statement 'bleeds' from one case to the next break;
at the end of every case
in a switch()
block. Frequently asked questions about the GNU C++ compiler - debugging on SVR4 systems
"How do I get debugging to work on my System V Release 4 system?"
Most systems based on System V Release 4 (except Solaris) encode symbolic debugging information in a format known as `DWARF'.
Although the GNU C compiler already knows how to write out symbolic debugging information in the DWARF format, the GNU C++ compiler does not yet have this feature yet. However, work is in progress for DWARF 2 debug support for gcc and g++ and will be available in a future release (probably 2.8.0).
In the meantime, you can get g++ debugging under SVR4 systems by configuring gcc with the
--with-stabs
option. This causes gcc to use an alternate debugging format, one more like that used under SunOS4. You won't need to do anything special to GDB; it will always understand the "stabs" format.
See also C programming style
When creating the class descriptions you will see that the example Bank Accounts classes contain three sections, namely public, private and protected, and this latter section is something new. Here is a simple difference between these three sections:-
· public - visible to the world and therefore usable by any other object
· private - visible solely within one object i.e. local to an object
· protected - visible to an object, its friends and any derived classes
Multiple inheritance
you are familiar with C++, you know that multiple inheritance allows an object to inherit the functionality of two or more classes. It can be a very powerful tool, but is not without its drawbacks. Base classes with identical function names, or even worse base classes with common base classes, can create headaches for even the most experienced developers.
Java gets rid of the headaches associated with multiple inheritance by not even supporting multiple inheritance. It can be argued that multiple inheritance isn't really necessary even in C++. Any time you think you need multiple inheritance it can usually be replaced by a container or delegate pattern. The title of this article may confuse you since Java doesn't actually support multiple inheritance. I'm going to show you some techniques that can be used to get the advantages of multiple inheritance without some of the drawbacks.
In order to accomplish this goal, we first need to know the drawbacks and advantages of multiple inheritance. Multiple inheritance allows us to give classes with different bases new common functionality. It allows us to add that functionality automatically while maintaining the code for the functionality in once place. On the other hand, multiple inheritance can cause a lot of confusion when two base classes implement methods with the same name. This results in two implementations for the same function identifier in the derived class. Java fixes the problem by only allowing classes in Java to inherit functionality from one class. This has the unfortunate side effect of removing all of the benefits you get from multiple inheritance. This article will show you how you can use interfaces and a delegate model to reclaim some of those benefits.
Classes in Java can only extend one class. However, classes can implement as many interfaces as they want. Let's talk for a little bit about what this means. Extending a class means the derived class inherits all of the data members, functions, and function definitions of the base class. The derived class can add to or completely replace implementations of the base class functions. The derived class will also show up as an instance of the base class when you use the operator "instanceof". Implementing an interface means the derived class must provide its own implementation for each function in the interface. There is no base functionality. If a class implements two interfaces that both happen to have identical functions, the derived class will only have one implementation of that function. While somewhat limiting, this removes a lot of the headaches associated with multiple inheritance. It is impossible for a class to inherit two sets of functionality for the same function name. If it happens to inherit the same function name from two different interfaces, the class is forced to resolve the conflict and callers to the class do not have to figure out which implementation to call.
Look at the version 001 of the Java files included with this article (see link at end of article). This program draws a line on the screen in Cartesian coordinates where the origin is in the lower left hand corner of the screen, the x-axis is positive to the right, and the y axis is positive to the top. Screen coordinates on the other hand have the origin at the upper left corner of the screen with the y-axis positive to the bottom. There are a few things that you should note about this program. First, both classes implement the functions called mapWorldToScreen and mapScreenToWorld. These functions convert screen coordinates to Cartesian coordinates and vice versa. If you want to change how your space is mapped (perhaps you would like to change the origin of the Cartesian space), you will need to make changes to both files. Second, CLine has to know that its parent is a CCartesianPlane object, and CCartesianPlane expects CLine as its child. This causes CLine to be strongly coupled to CCartesianPlane. If we wanted to add a new shape, it would be nearly impossible at this point. While not really dealing with multiple inheritance, strong coupling is something you generally want to avoid because it reduces the flexibility and reusability of your code.
Version 002 takes a first step towards multiple inheritance by defining an interface that both classes can support to map points between the screen and Cartesian spaces. We now have two disjoint classes with similar functionality that can be referenced the same way. The cast to CCartesianPlane in CLine has been changed to a cast to ICoordinateSpace. It is worth noting here that casting an object like this is considered to be weak object oriented program. It could be argued that the ICoordinateSpace interface should support the concept of a parent instead of using the Component's parent. When we are dealing with interfaces, I usually break this rule of OOP. My feeling is that the class knows what interfaces it uses and can act accordingly if a member variable does not support that interface.
The implementations of ICoordinateSpace in CCartesianPlane and CLine still duplicate a lot of code. Version 003 puts all of this duplicated code into a new class called CCoordinateSpaceImplBase. This new class provides a base implementation of ICoordinateSpace. CLine and CCartesianPlane now contain an instance of CCoordinateSpaceImplBase. The implementations of ICoordinateSpace are now routed to this data member. Had the classes been derived from CCoordinateSpaceImplBase, these calls would have looked something like "super.mapScreenToWorld(p)". CCartesianPlane still provides its own implementation of mapScreenToWorld and mapWorldToScreen. In a sense, it is overriding the functionality of its 'base class' CCoordinateSpaceImplBase.
The base functionality for ICoordinateSpace is now contained in a single class. If we want to change how our coordinate space works, all we need to do is change this one file. We have now recovered two of the benefits of multiple inheritance. The third benefit, automatically inheriting default behavior, will not be possible with this method. However, if you compare the code in CLine and CCartesianPlane, you will notice that it is almost identical. You could copy this code directly into a new class to obtain the new results. So, while the inheritance isn't quite automatic, it is extremely easy to add.
Although the examples themselves aren't very exciting, it could be jazzed up with new shapes or perhaps even transforms to rotate and scale the coordinate spaces. What is exciting is your ability to approximate multiple inheritance in Java. I hope you find this technique as useful as I have. If you have any comments or questions, please e-mail [email protected].
Multi-Inheritance_Java_Examples.zip contains code examples described by this article.
Get Multi-Inheritance_Java_Examples.zip (16K).
You do know what "private parts" are, right? ;) Now with the help of Grady Booch you can understand what are friends for! :)
... C++ offers even more flexible control over the visibility of member objects and member functions. Specifically, members may be placed in the public, private, or protected parts of a class. Members declared in the public parts are visible to all clients; members declared in the private parts are fully encapsulated; and members declared in the protected parts are visible only to the class itself and its subclasses. C++ also supports the notion of *friends*: cooperative classes that are permitted to see each other's private parts.
-- Grady Booch, "Object Oriented Design with Applications"
A friend function is not a class member and yet it can have access to private and protected members of a class. Friends are not called by using member selection operators such as " . or ->" unless they are members of another class. Friend functions can be defined inside a class declaration. Friend functions declared within a class are inline just like other inline member functions. These functions act as though they were defined immediately after all class members have been seen but before the end of the class declaration. Even though friend functions are declared inside class declarations, they are not considered in the scope of the enclosing class. They are normally considered in the file scope. An entire class can be declared as a friend of another class.
To declare a function as a friend of a class, put the word "friend" before the function prototype in the class definition. For example, you want to show that ClassTwo is a friend of ClassOne, simply put the word "friend" in front of ClassTwo like:
friend class ClassTwo;
This line should be inside the definition of class ClassOne and declared explicitly. The friendship between ClassOne and ClassTwo is neither symmetric nor transitive. This means that ClassTwo is a friend of ClassOne but ClassOne cannot be assumed to be a friend of ClassTwo. Same concept applies when you have multiple classes connected by multiple friendships. Friendship can only go one way.
A partial example of friends accessing private members of a class goes something like this:
class ClassOne{
// friend declaration should appear before the declaration of public and private member function
friend void ClassTwo ( ClassOne &, int); // friend declaration
public:
Count( ) { x = 0; } // constructor
Void print( ) const { cout << x << endl;} // output
Private:
Int x; // data member
};//ClassTwo is declared as a friend function of ClassOne
void ClassTwo( ClassOne &c, int val)
{
c.x = val;
}
int main( )
{
ClassOne counter;
counter.print ( );
ClassTwo( counter,10); // set x with a friend
Counter.print( );
Return 0;
}The purpose of using friend function is to improve performance. Sometimes when a member function cannot be used in a certain operation, using friends would be able to solve that problem.
A virtual function is declared in a base class of a program and can then be redefined in each derived class. Virtual functions give you polymorphism, which means derived classes can implement the same function differently. The declaration in the base class acts as a kind of template which can be enhanced by each derived class.
class vehicle { public: virtual void run(); }; void func(vehicle* v) { v->run(); }
In the above code, the 'run' method called by function 'func' is not necessarily vehicle::run method. It may be car::run or train::run ( where car and train are derived from vehicle class and they override the run method). The actual run method called depends where 'v' points. If 'v' points to a car object, then car::run is called and so on.
While compiling the above code compiler may not see the derived classes (car, train etc.) of vehicle class. So compiler has to somehow arrange to call car::run or train::run depending on where 'v' points. This is called dynamic binding.
When you have a pointer to an object, the object may actually be of a class that is derived from the class of the pointer (e.g., a Vehicle* that is actually pointing to a Car object). Thus there are two types: the (static) type of the pointer (Vehicle, in this case), and the (dynamic) type of the pointed-to object (Car, in this case).
Static typing means that the legality of a member function invocation is checked at the earliest possible moment: by the compiler at compile time. The compiler uses the static type of the pointer to determine whether the member function invocation is legal. If the type of the pointer can handle the member function, certainly the pointed-to object can handle it as well. E.g., if Vehicle has a certain member function, certainly Car also has that member function since Car is a kind-of Vehicle.
Dynamic binding means that the address of the code in a member function invocation is determined at the last possible moment: based on the dynamic type of the object at run time. It is called "dynamic binding" because the binding to the code that actually gets called is accomplished dynamically (at run time). Dynamic binding is a result of virtual functions.
**** 15 Polymorphism & Virtual Functions. from Thinking in C++, 2nd ed. Volume 1 ©2000 by Bruce Eckel. Here is a fast mirror of Thinking in C++
Polymorphism (implemented in C++ with virtual functions) is the third essential feature of an object-oriented programming language, after data abstraction and inheritance.
It provides another dimension of separation of interface from implementation, to decouple what from how. Polymorphism allows improved code organization and readability as well as the creation of extensible programs that can be "grown" not only during the original creation of the project, but also when new features are desired.
Encapsulation creates new data types by combining characteristics and behaviors. Access control separates the interface from the implementation by making the details private. This kind of mechanical organization makes ready sense to someone with a procedural programming background. But virtual functions deal with decoupling in terms of types. In Chapter 14, you saw how inheritance allows the treatment of an object as its own type or its base type. This ability is critical because it allows many types (derived from the same base type) to be treated as if they were one type, and a single piece of code to work on all those different types equally. The virtual function allows one type to express its distinction from another, similar type, as long as they're both derived from the same base type. This distinction is expressed through differences in behavior of the functions that you can call through the base class.
In this chapter, you'll learn about virtual functions, starting from the basics with simple examples that strip away everything but the "virtualness" of the program.
**** Chapter 16- Polymorphism, late binding and virtual functions from C++ Annotations Version 4.4.2
**** www.objectmentor.com/publications/abcpvf.pdf Abstract Classes and Pure Virtual Functions -- not bad explanation despite OO fundamentalist style
**** CS170 C++ Virtual Functions Lab -- Department of Computer Science, University of Regina. From CS170 Labs Index
**** [19] Inheritance -- virtual functions, C++ FAQs Lite, ...
C++ Inherited Virtual Function Declarations and Definitions
If a class base contains a virtual function vf, and a class derived derived from it also contains a function vf of the same type, then a call of vf for an object of class derived invokes derived::vf (even if the access is through a pointer or reference to base). The derived class function is said to override the base class function. If the function types are different, however, the functions are considered different and the virtual mechanism is not invoked. It is an error for a derived class function to differ from a base class' virtual function in the return type only.
C++ Q&A- Inline Virtual Functions, AVI Files in EXEs, and ... by Paul DiLascia (Microsoft) . How does C++ handle inline virtual functions? When a function is inline and virtual, will code substitution take place or is the call resolved using the vtable?
Eiffel vs. C++ (by Bertrand Meyer - 4 June 89)
Dynamic binding Dynamic binding is the default mechanism for routine calls in Eiffel (achieved without any undue effect on performance). The default policy in C++ is static binding; dynamic binding is only applied to routines declared as ``virtual''. This may look like an acceptable requirement to impose on programmers but I believe it is not. The whole idea of inheritance is that you may reuse a class later on by writing a descendant and adapting it to new uses by overriding some of the routines of the original - within the original semantic constraints, as defined by assertions. This should be done without impacting the original, which may be used by many other ``client'' classes. (These concepts are explained in my book ``Object-Oriented Software Construction, Prentice-Hall, 1988, as the ``Open-Closed Principle'', section 2.3.) In such a case the designer of the original routine may have had no inkling whatsoever that the routine would ever be redefined and subjected to dynamic binding. This is incompatible with the requirement that the original designer should have declared the routine as virtual in the first place. Instead of forcing the programmer to take care of low-level optimizations, the Eiffel approach makes the compiler responsible for exploiting the performance of static over dynamic binding. The optimizer, working on a set of classes, generates code that applies static binding to any routine which warrants it (because it is never redefined). Performing tedious and potentially dangerous optimizations in a safe way should be the role of computers, not humans.
[20] Inheritance virtual functions, C++ FAQ Lite
Virtual Functions from C++ versus C
C++ internals - Virtual Functions
Virtual functions in constructors
Implementation issues
A colleague informs me that virtual functions are now more commonly implemented via thunks (instead of class vtbls). He couldn't cite a source for this. Can you?
[I would be astonished if this were true, regardless of whether he means real Algol-style thunks or Microsoft's misnamed function wrappers. Every C++ compiler I've ever seen uses vtbls, perhaps optimized to a straight call when the compiler or linker can be sure it'll never be overridden. -John]
Comp.compilers Re New Implementation of Virtual Functions in C++
Maybe he's thinking not of the functions themselves, but of the class
pointer adjustment for multiple inheritance.
In earlier (CFront based, I think) implementations of multiple inheritance, class vtbls used two "words" per function: A pointer to the function code and an offset for adjusting the class pointer. This introduced a time and space disadvantage, so some vendors (I remember Apple's MPW C++ compiler) introduced language extensions to declare that some class would only be used as a base class in single inheritance hierarchies.
Newer implementations (I specifically know that Metrowerks CodeWarrior switched to this at some point) only use a single "word", the pointer to the function code. If the class pointer *does* need to be adjusted, a thunk is generated.
This probably saves both space and time since in many programs, the vast majority of virtual calls don't need to adjust the class pointer (code is in most derived class or in a base class starting at the same physical address as the most derived class).
Matthias
C++ Templates Tutorial see also google cashe templates.htm+c%2B%2B+templates&hl=en
C++ Templates -- tips
C++ Templates - Integer Parameters
C++ Templates as Partial Evaluation
CSE2305-CSC2050 Topic 20 C++ Templates
Five compilation models for C++ templates (ResearchIndex)
next-prog archive- SUMMARY- C++ Templates
C++ Templates and the STL from Contents CPPvm: C++ Interface to PVM (Parallel Virtual Machine)
CIS 251 OOP -- C++ Templates and Genericity
comp.std.c++ frequently asked questions
Compile Time Symbolic Derivation with C++ Templates
Brad Appleton's C++ Links good collection of links
Cliff's Teaching Info and Technical Resources
CP Archives - March 1999 - The C++ Interview
by Alex Bykov
How do you rank your C++ skills on a scale of 1 to 10?
This is often the first question you will hear on an interview for a C++ contract. You will be tempted to rate yourself high, and you should. This is your chance to convince the client that you are just what he is looking for--an assertive and knowledgeable professional who will be productive either working on a team or on your own. Naturally, though, you should be able to support the ranking you gave yourself by doing well on the interview. This article will help you prepare for your C++ interview.
I put together a list of 40 questions that I have had to answer during numerous technical interviews in the past few years. You, too, will have to answer at least some of them during an interview. Even if you use C++ on a daily basis, it pays to go through the questions. Most of us, no matter how experienced, use only a segment of the language that we are most comfortable with. Brief answers are included, but you can find more information in the references listed.
Q1. Is there anything you can do in C++ that you cannot do in C?
A1. No. There is nothing you can do in C++ that you cannot do in C. After all you can write a C++ compiler in C.
Q2. What is the difference between C++ structure and C++ class?
A2. The default access level assigned to members of struct is public while the default access level assigned to a class is private.
Q3. What is encapsulation?
A3. Encapsulation is welding of code and data together into objects.
Q4. What is inheritance?
A4. Inheritance is a mechanism through which a subclass inherits the properties and behavior of its superclass.
Q5. What is polymorphism?
A5. In Greek this means "many shapes." As a consequence of inheritance and virtual functions, a single task (for example, drawing a geometrical shape) can be implemented using the same name (like draw()) and implemented differently (via virtual functions) as each type in object hierarchy requires(circle.draw() or rectangle.draw()). Later, when a polymorphic object (whose type is not known at compile time) executes the draw() virtual function, the correct implementation is chosen and executed at run time.
Q6. What would you say if you saw "delete this" while reviewing your peer's code?
A6. You should never do this. Since compiler does not know whether the object was allocated on the stack or on the heap, "delete this" could cause a disaster.
Q7. What is the difference between public, protected, and private members of a class?
A7. Private members are accessible only by members and friends of the class. Protected members are accessible by members and friends of the class and by members and friends of derived classes. Public members are accessible by everyone.
Q8. What is the difference between non-virtual and virtual functions?
A8. The behavior of a non-virtual function is known at compile time while the behavior of a virtual function is not known until the run time.
Q9. What is a pure virtual function?
A9. "A pure virtual function is a function declared in a base class that has no definition relative to the base."
Q10. What is an abstract base class?
A10. It is a class that has one or more pure virtual functions.
Q11. What is the difference between MyClass p; and MyClass p();?
A11. MyClass p; creates an instance of class MyClass by calling a constructor for MyClass. MyClass p(); declares function p which takes no parameters and returns an object of class MyClass by value.
Q12. How do you know that your class needs a virtual destructor?
A12. If your class has at least one virtual function, you should make a destructor for this class virtual. This will allow you to delete a dynamic object through a pointer to a base class object. If the destructor is non-virtual, then wrong destructor will be invoked during deletion of the dynamic object.
Q13. Why were the templates introduced?
A13. Many data structures and algorithms can be defined independently of the type of data they work with. You can increase the amount of shared code by separating data-dependent portions from data-independent portions, and templates were introduced to help you do that.
Q14. What is a static member of a class?
A14. Static data members exist once for the entire class, as opposed to non-static data members, which exist individually in each instance of a class.
Q15. What feature of C++ would you use if you wanted to design a member function that guarantees to leave "thisΣ object unchanged?
A15. It is "const" as in: "int MyFunc (int test) const;"
Q16. Can you overload a function based only on whether a parameter is a value or a reference?
A16. No. Passing by value and by reference looks identical to the caller.
Q17. What is the difference between function overloading and function overriding?
A17. Overloading is a method that allows defining multiple member functions with the same name but different signatures. The compiler will pick the correct function based on the signature. Overriding is a method that allows the derived class to redefine the behavior of member functions which the derived class inherits from a base class. The signatures of both base class member function and derived class member function are the same; however, the implementation and, therefore, the behavior will differ.
Q18. Can derived class override some but not all of a set of overloaded virtual member functions inherited from the base class?
A18. Compiler will allow this, but it is a bad practice since overridden member functions will hide all of the inherited overloads from the base class. You should really override all of them.
Q19. What is the difference between assignment and initialization in C++?
A19. Assignment changes the value of the object that has already been constructed. Initialization constructs a new object and gives it a value at the same time.
Q20. When are copy constructors called?
A20. Copy constructors are called in three cases: when a function returns an object of that class by value, when the object of that class is passed by value as an argument to a function, and, finally, when you construct an object based on another object of the same class (Circle c1=c2;).
Q21. Why do you have to provide your own copy constructor and assignment operator for classes with dynamically allocated memory?
A21. If you don't, the compiler will supply and execute the default constructor and the assignment operator, but they will not do the job correctly. The default assignment operator does memberwise assignment and the default copy constructor does memberwise copy. In both cases you will only assign and manipulate pointers to dynamic memory, which will lead to memory leaks and other abnormalities. You should write your own assignment operator and copy constructor, which would copy the pointer to memory so that each object has its own copy.
Q22. Does compiler guarantee that initializers will be executed in the same order as they appear on the initialization list?
A22. No. C++ guarantees that base class subobjects and member objects will be destroyed in the opposite order from which they were constructed. This means that initializers are executed in the order, which supports the above-mentioned guarantee.
Q23. What is function's signature?
A23. Function's signature is its name plus the number and types of the parameters it accepts.
Q24. What does extern "C" int func(int *, Foo) accomplish?
A24. It will turn off "name mangling" for this function so that one can link to code compiled by C compiler.
Q25. Why do C++ compilers need name mangling?
A25. Name mangling is the rule according to which C++ changes function's name into function signature before passing that function to a linker. This is how the linker differentiates between different functions with the same name.
Q26. What is the difference between a pointer and a reference?
A26. A reference must always refer to some object and, therefore, must always be initialized; pointers do not have such restrictions. A pointer can be reassigned to point to different objects while a reference always refers to an object with which it was initialized.
Q27. How can you access the static member of a class?
A27.
<ClassName>::<StaticMemberName>. Q28. How are prefix and postfix versions of operator++() differentiated?
A28. The postfix version of operator++() has a dummy parameter of type int. The prefix version does not have dummy parameter.
Q29. What functions does C++ silently write and call?
A29. Constructors, destructors, copy constructors, assignment operators, and address-of operators.
Q30. What is the difference between new/delete and malloc/free?
A30. Malloc/free do not know about constructors and destructors. New and delete create and destroy objects, while malloc and free allocate and deallocate memory.
Q31. What is the difference between delete and delete[ ]?
A31. Delete deletes one object; delete[ ] deletes an array of objects.
Q32. Name two cases where you MUST use initialization list as opposed to assignment in constructors.
A32. Both non-static const data members and reference data members cannot be assigned values; instead, you should use initialization list to initialize them.
Q33. What is the difference between const char *myPointer and char *const myPointer?
A33. Const char *myPointer is a non constant pointer to constant data; while char *const myPointer is a constant pointer to non constant data.
Q34. Suppose that objects A, B, and C are instances of class MyClass (MyClass A, B, C;). How should you design an assignment operator so that the "A=B=C;" statement would be allowed by a compiler but "(A=B)=C;" would not be allowed by a compiler?
A34. Make operator=return a reference to a const object.
Q35. Is there any problem with the following: char *a=NULL; char& p = *a;?
A35. The result is undefined. You should never do this. A reference must always refer to some object.
Q36. Class B is derived from class A. Function f is A's friend. Is f B's friend as well?
A36. No. Friendship cannot be inherited.
Q37. What issue do auto_ptr objects address?
A37. If you use auto_ptr objects you would not have to be concerned with heap objects not being deleted even if the exception is thrown.
Q38. What happens when a function throws an exception that was not specified by an exception specification for this function?
A38. Unexpected() is called, which, by default, will eventually trigger abort().
Q39. Why should you prefer throw/catch mechanism to setjmp/longjmp?
A39. The main problem with longjmp() is that it does not destroy local objects properly.
Q40. Can you think of a situation where your program would crash without reaching the breakpoint which you set at the beginning of main()?
A40. C++ allows for dynamic initialization of global variables before main() is invoked. It is possible that initialization of global will invoke some function. If this function crashes the crash will occur before main() is entered.
If you feel comfortable answering these questions, then rest assured that your chances of impressing any interviewer are very high. Be prepared to know basic computer science concepts such as data structures, search and sort algorithms, basic database concepts, etc. The client's needs will determine what particular branch of computer science you have to be familiar with, but you should always be ready to implement the stock, the queue, and the linked list data structures with either C or C++ programming languages. And know how to write your own version of strcpy (string copy) in C programming language since very often they ask you to do that.
[Aug 11, 2003] C++ Memory Management: From Fear to Trimph, part 3 George Belotsky explains Common C++ Memory Management Errors and C++ Memory Management Principes in two previous article. He concludes his series by exploring good memory management in C++. [ Linux DevCenter]
See also Skeptical OO page
OOP Criticism -- good OOP criticism and OOP problems (The emperor has no clothes!).
OO zealots critique
Dr. Dobb's Journal Spring 1998 Passing the C++ Test
C ++ Syntax Computer Free Test Quiz Online
Quia - Java Quiz - AP C++ Quiz #1
C-C++ Programming - Fall 1999 - Quiz III - November 9, 1999
CSC100- Introduction to C and C++ (quiz #0)
Sean Corfield's site summarizing the changes from ARM C++ to Standard C++.
Gnarly New C++ Language Features
Addison-Wesley Innovations Interview (1997)
Innovations: Who is the audience for this book? Stroustrup: All C++ programmers, and all experienced programmers who would like to learn C++. Also, students who already know how to program and want to learn C++ and the techniques it supports. It is not a book for people who have never programmed before or have only the most casual acquaintance with programming. Innovations: What is different in this edition? Innovations: What are new features that C++ programmers must know about? Innovations: Where do you see C++ used in the future? Innovations: What are the more difficult parts of the C++ programming language to learn?
How are you addressing the problems? Innovations: Is a thorough understanding of object-oriented design required to learn
C++? Innovations: How much of the new C++ standard libraries does a programmer need to know
to develop industrial applications? Stroustrup: As much as is needed for the application in hand.
Seriously, the standard libraries provide many useful facilities as well as examples of many general
techniques. I mine the standard library for useful techniques. However, it takes far less knowledge
to use a library than to understand it completely. I give overviews of facilities so that people
can select what they want and quickly find more information about the library facilities they
decided to use. The book's extensive index and cross referencing are very important for programmers
who use the library before they have read all of the book and or even the library section - and
most programmers will do that. Innovations: What is the difference between STL and the standard libraries? Innovations: Why is C++ the best language for mission critical application development
and large scale development? Innovations: What does final-draft standard mean? What does ANSI/ISO standardization
mean for the C++ programming language? Innovations: Given that the C++ language, and especially its standard library, has grown
so much since the second edition of the book, did new pedagogical challenges arise? Innovations: What is the one C++ feature you find most valuable, and which one do you
find least valuable? Innovations: How does a new programmer choose between learning C++ and learning Java? Innovations: Are you satisfied with the scope of the changes introduced as part of the
ISO standardization process? Are there any features left out that you would have preferred to
have included? |
Stroustrup C++ links
On the important of the quality of diagnostics in programming languages:
From:
Nikolai Bezroukov ([email protected]) Subject: Re: Dissertation on programming languages Newsgroups: comp.edu
Date: 1999/07/05 |
Caroline,
I believe that C++ is a disaster as a first language -- it is just too complex.
Java is slightly better, and has (somewhat) simpler string handling, but usually it is also a torture for students, unless you find a suitable subset.
Implementations of both languages are extremely bad in diagnostic quality. And the quality of implementation is as important as the language itself. Often one can be better off with a decent implementation of even old language (Basic, Pascal) that with bad implementation of a new one (Karel++ http://csis.pace.edu/~bergin/karel.html is a well known example of a decent first language -- Java-like Logo with a horrible implementation).
OO-related complexity is an additional drawback, also it can (and IMHO should) be avoided during at least first semester. Here C++ is preferable as one can completely ignore OO at the beginning, and introduce it later, but subsetting Java will also work.
Anyway I would try to outline a subset of Java and compare implementations to find more or less suitable for introductory course if any.
I really hate to see how students serve as guinea pigs for some new and untested language just to satisfy ambitions of the teacher. And misuse of OO in teaching introductory courses is a bad thing. It's just the same self righteous religious fundamentalism that we see in other spheres of life so often.
Dr. Nikolai Bezroukov www.softpanorama.org
Standard disclaimer applies [email protected] wrote:
> I am currently completing a Masters Degree in Computing & Information > Systems. As part of the program I am obliged to submit a > dissertation/thesis. The topic I have chosen is: "Which Programming > Language should be taught to Students first?" (I am mainly concentrating > on C++ and Java, as these are the languages I know.) If anyone has any > information on this topic, or knows any useful web sites/books etc, > which will help me, please let me know. Thank You. > > Sent via Deja.com http://www.deja.com/ > Share what you know. Learn what you don't.
Gnarly New C++ Language Features
OOP with C++: Online Course/Slides
Porting C++ to Java: Index
Smart pointer templates in C++
Society
Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers : Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism : The Iron Law of Oligarchy : Libertarian Philosophy
Quotes
War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda : SE quotes : Language Design and Programming Quotes : Random IT-related quotes : Somerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose Bierce : Bernard Shaw : Mark Twain Quotes
Bulletin:
Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 : Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law
History:
Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds : Larry Wall : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOS : Programming Languages History : PL/1 : Simula 67 : C : History of GCC development : Scripting Languages : Perl history : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history
Classic books:
The Peter Principle : Parkinson Law : 1984 : The Mythical Man-Month : How to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Haters Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite
Most popular humor pages:
Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor
The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D
Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.
This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...
|
You can use PayPal to to buy a cup of coffee for authors of this site |
Disclaimer:
The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.
Last modified: April 23, 2019