|
Softpanorama
(slightly skeptical)
Open Source Software Educational Society |
May the
source be with you,
but remember the KISS principle ;-)
|
Slightly Skeptical C++ Links
C++ as a Multiparadigm Language
(or C++ without OO overdose ;-)
"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:
Concepts,
Techniques, and Models of Computer Programming
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 usually
consist of data) with procedures that are included in the class (member functions).
This approach with slightly different syntactic sugar later was called OO programming.
Althouth 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). The second innovation --
coroutines (and related concept of
internal pipes) is absent in 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, 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. The major such innovation is the concept of templates
and namespaces. Namespaces permit more manageable structuring of name space and
is a very important language construct of its own, 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. On high end one should consider learning STL that contains a library
of important algorithms.
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:
- The learning version of VC6 can be bought with
several books. The amount of books
for VC6 exceed all other compilers. This is the mainstream compiler and sometimes
it makes perfect sense to follow mainstream. Reasonable quality of diagnostic,
reasonable debugger support. Good documentation. You need to apply patches from
Microsoft WEB site after installing the compiler.
- High quality
Borland
C++ Compiler 5.5 is now free. It provides a decent diagnostic and good debugger.
But this compiler has less books devoted to it then VC6.
-
Intel C++ compiler is available with a non-commercial license, meaning that
anyone can download and use the full compiler for non-profit work. This is the
best optimizing compiler you can get. The installation of Intel compiler is
far faster and easier than the installation of Visual Studio .NET.
The Intel compiler scores are approximately 2.5 times
better then gcc 3.2.1 for the Monte-Carlo simulation, which is a considerably
larger margin than for any of the other parts of the SciMark 2.0 benchmark.
For other parts it is outperforming by only small margins of 10% or less. See
Benchmarking Intel C++ against GNU gcc on Linux.
Never study C++ as if it is limited to OO. OOP isn't a panacea (from the
point of view of programming productivity combination 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.
Like for a hummer everything in the world is a nail, for OO evangelists everything
in the world is 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 -- OOP criticism and OOP problems
(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 semi ignorant
instructors ;-). OO religion with its 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) 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, 15,000 line, and 25,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 arise 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. 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). 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 better then Java debuggers :-)
Dr. Nikolai Bezroukov
Notes:
- Those pages are written by people for whom English is not a
native language. Some amount of grammar and spelling errors
should be expected.
- This is a Spartan WHYFF (We Help You For Free) site. It
cannot replace the best teachers and
the
best books.
- The site contain some obsolete pages as it develops like a
living tree... Some links on older pages
are broken. Please
try to use Google, Open directory, etc. to find a replacement link
(see
HOWTO search the WEB for details).
We would appreciate if you can
mail us a correct link.
|
|
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.
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?
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.
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.
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!
Actually Spolsky does not understand the role of scripting languages.
But hi is right of target with his critique of OO. Object oriented programming is
no silver bullet.
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.
Microsoft COM
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
|
About:
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.
|
[Feb 14, 2006]
OOP Criticism Object Oriented Programming Oversold by B. Jacobs.
OOP criticism and OOP problems. The emperor has no clothes! Reality Check
101. Snake OOil. Updated: 5/14/2005
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
[Feb 14, 2006] Free Microsoft compilers
- Get
a Free Copy of Visual Studio 2005 Express Editions
Download a copy of Visual Studio 2005 Express Editions
today – easy to use tools for the hobbyist, novice and student developer.
-
Visual C++ Toolkit 2003 The Microsoft Visual C++ Toolkit 2003 includes the
core tools developers need to compile and link C++-based applications for Windows
and the .NET Common Language Runtime – compiler, linker, libraries, and sample
code.
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
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
Dinkum C-C++ Library Reference by P.J. Plauger.
The Standard
Template Library: Reference to STL maintained by Silicon Graphics.
C++
Reference Material -- nice site
The ISO/ANSI
C++ Standard: New C++ standard as of 1998.
g++ info at Cygnus.
C++
Standards FAQ
C++ Standards
and Architecture, Nat Myers
Information About IOstreams
Operator Precedence and Associatively Rules in C & C++
C++ quick-reference -- small printable quick reference
C++
Programming Language Tutorial Handouts
C++ Technical Manual: An extensive description of the C++ language,
including the new standard.
Learning
C++: A student's on-line C++ tutorial.
C++ FAQ:
Descriptions and examples of the syntax of C++.
Bruce Eckel's Home
Page - C++ and Java: Eckel's book Thinking in C++. Can serve
as reference
ACM Classic Articles
COMP435 - References and Pointers a-nd Constants, Oh My!
Microsoft Visual Studio 6.0 Service Pack 5 - Download
Namespaces:
Scoping and visibility rules:
-
O'Reilly Network Programming with Exceptions in C++ [May. 05, 2003]
- *****
Handling Exceptions in C and C++, Part 1 by Robert Schmidt, May 10, 1999
In his inaugural column, Robert Schmidt shows you how to handle exceptions
in C++.
-
Handling Exceptions in C and C++, Part 2
-
Handling Exceptions in C and C++, Part 3
-
Handling Exceptions in C and C++, Part 4
-
Handling Exceptions, Part 5
-
Handling Exceptions, Part 6
-
Handling Exceptions, Part 7
-
Handling Exceptions, Part 8
-
Handling Exceptions, Part 9
-
Handling Exceptions, Part 10
-
Handling Exceptions, Part 11
Handling Exceptions, Part 12
-
Handling Exceptions, Part 13
-
Handling Exceptions, Part 14
-
Handling Exceptions, Part 15
- EDM-2 - OOPS
Avenue - C++ Exceptions -short intro
-
C++ Exceptions
-
-- a very good paper
-
March 96 - Using C++ Exceptions in C
-
SPC
Seminar Series - C++ Exceptions and C++ Under the Hood
-
Exceptions: Using MFC Macros and C++ Exceptions
- C++
Exceptions
-
MFC Programmer's SourceBook : C++ & MFC
- EDM/2 - OOPS
Avenue - C++ Exceptions
-
Exception Handling Topics (C++)
-
Exception Handling Differences
-
C++ Exceptions. Review.
-
C++ Exceptions
- Teach Yourself C++, 5th ed. Al Stevens. MIS:Press (1997).
- C++ How to Program, 2nd ed. Deitel & Deitel. Prentice-Hall (1998).
-
Error
Handling with C++ Exceptions, Part 1
-
March 96 - Using C++ Exceptions in C
-
Software Techniques/Structured Exception Handling - slides
-
Exceptions (see Ch 16) -- slides by David Till
- Java exception handling -- slightly different, but some materials might
be useful
-
Handling Errors with Exceptions
The Java TM Tutorial Start of Tutorial > Start of Trail Search Feedback
Form Trail : Essential Java Classes Lesson: Handling Errors with Exceptions
If there's a golden rule of programming it's this: Errors occur in software
programs.
-
Exceptions in Java - JavaWorld July 1998 by Bill Venners. For those
of you who need a refresher on exceptions, this cover story companion piece
is a valuable tutorial on the nuts and bolts of what exceptions are and
how they work in the Java language and virtual machine.
-
Designing with exceptions - JavaWorld July 1998 -- This installment
of the Design Techniques column discusses design guidelines that pertain
to exceptions. It focuses primarily on how to decide when to use exceptions,
and gives several examples
-
How exceptions work - JavaWorld June 1996 -- Comprising one of the critical
features of the Java programming language, exceptions allow for changing
the flow of control when some important or unexpected event, usually an
error, has occurred.
How the Java virtual machine handles exceptions - JavaWorld January 1997
--All Java programs are compiled into class files that contain bytecodes,
the machine language of the Java virtual machine. This article takes a look
at the way exceptions are handled by the Java virtual machine, including
the exception table.
Dealing with Exceptions from Sun's Java Tutorial
****
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++
C-C++ Pointers
tutorial
Humor
C++ style and pointers
Book reviews
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)
Visual C++ Guide - Debugging
Program Styles & Debugging Tools in Visual C++
Debugging with MS 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
- Check that you have arrows, not commas, between every 2 items (variables,
strings, function calls, etc., all count as separate items.
- Loop or decision statement doesn't work
- Check for semicolons at the end of a loop or decisiont statement. They don't
belong there (
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
- There must be a
break; at the end of every case
in a switch() block.
- Wrong answer to a seemingly correct formula
- Remember operator precedence! Start by adding lots of parentheses--it can't
hurt to have a lot of them! This is especially important in complex formulas
where the precedence may be obvious to you, but not to the compiler.
-
BITPEN Week 13 Lecture 1 - C++ Debugging on Unix
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
Inheritance in C++
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