Future of C++

K

kwikius

My hunch is my posts to clc++ are disappearing down a hole, so I post here
instead.

Future of C++ thread on clc++

Abhishek said:
Hi All,
This is a non-technical off topic post, so please excuse me for that.

I wanted to understand from the Gurus of C++ out here about their opinion
on
the future of C++. I have spent eight plus years in the software industry
working in applications programming on C++/ Windows. My current company is
now moving big time towards Java/ J2EE based technologies. Most of the
other
companies which are writing application software are also moving (or have
alreadt moved) to J2EE or to .Net. So is there no future for C++ in
application software? What do the people on this group feel about it?

I understand that Systems side and Embedded are still the areas where C++
is
being used well. But is that all? What do the people who have invested
time
and energy in C++ should do? Learn Java or C# because a significant
majority
of other developers (apparently) could not free the pointers and found
garbage collector to be a great idea.

Thoughts/ Suggestions/ Criticism?


AFAICS C++ is very much about a "craft" approach to software development.
For one It takes a long time to get good at it. Like any craftsman, say a
carpenter it costs. Once upon a time if you wanted a new door, you asked the
carpenter and he made you one to your spec. These days doors are all
standard sizes and you buy them off the shelf at a hardware superstore. A
similar situation applies with C++ and other languages in respect to
libraries. The modern trend is towards abstracting away the hardware. This
results in a loss of performance but much greater productivity, and
critically libraries which become unofficial standards within the language.
The classic example in C++ is GUI. Often newbies ask about the C++ GUI and
they are vaguely pointed off towards various libraries. In modern languages
there are usually one or two "standard" GUI libraries that everyone uses.

Because C++ is so expressive, if you start a new library ( or even
application ) then you are presented with a huge number of decisions. Do I
use templates or RTTI, Do I use Dll or static libs, Do I worry about cross
platform or target one. This all takes a long time and results in
fragmentation. In other less complicated languages, you don't have to worry
about these things. They have been solved or abstracted away. Hence
languages like Java, and Python have huge libraries because presumably they
are easier to write once in practise. The low level problems that confront
you in C and C++ are abstracted away.

That said C++ and C will be around a long time. For windows they will be
around as long as its around I guess, but I don't see there being as much
demand for C++ programmers.

regards
Andy Little
 
P

Pavel

kwikius said:
My hunch is my posts to clc++ are disappearing down a hole, so I post here
instead.

Future of C++ thread on clc++




AFAICS C++ is very much about a "craft" approach to software development.
For one It takes a long time to get good at it. Like any craftsman, say a
carpenter it costs. Once upon a time if you wanted a new door, you asked the
carpenter and he made you one to your spec. These days doors are all
standard sizes and you buy them off the shelf at a hardware superstore. A
similar situation applies with C++ and other languages in respect to
libraries. The modern trend is towards abstracting away the hardware. This
results in a loss of performance but much greater productivity, and
critically libraries which become unofficial standards within the language.
The classic example in C++ is GUI. Often newbies ask about the C++ GUI and
they are vaguely pointed off towards various libraries. In modern languages
there are usually one or two "standard" GUI libraries that everyone uses.

Because C++ is so expressive, if you start a new library ( or even
application ) then you are presented with a huge number of decisions. Do I
use templates or RTTI, Do I use Dll or static libs, Do I worry about cross
platform or target one. This all takes a long time and results in
fragmentation. In other less complicated languages, you don't have to worry
about these things. They have been solved or abstracted away. Hence
languages like Java, and Python have huge libraries because presumably they
are easier to write once in practise. The low level problems that confront
you in C and C++ are abstracted away.

That said C++ and C will be around a long time. For windows they will be
around as long as its around I guess, but I don't see there being as much
demand for C++ programmers.

regards
Andy Little

A couple of bare facts/observations with minimal comments:

1. A younger co-worker of mine left for Microsoft last week. What's
interesting, they took him to take part in writing their next generation
Visual Studio or whatever they will call it -- and it is going to be the
first version of it written wholly in C# (instead of C/C++, in which all
recent previous versions have been written). Maybe second next Windows
version will not be in C/C++ either? :)

2. I received the last issues of last professional C++ magazine I knew
(C/C++ User Journal) more than a year ago (I think). I then checked on
C++ Reports that I used to read much earlier just to learn it had been
dead for quite a while already. Was not very happy about it; this
newsgroup seems to be one of very few C++ dedicated resources.

I would not mind to read a civilized discussion about where C++ is
heading and why -- and I have some ideas of my own about it -- but not
sure if such discussion is an off-topic here or whether there is enough
interest. Also the topic may be quite flame-prone. Any opinions?

-Pavel
 
M

Matthias Buelow

To increase in emphasis on statically verifiable type safety. If you
want type safety, you should be expressive. I believe being less
expressive lead us to script programming.

I don't quite understand that statement. What do you mean? Static typing
and expressiveness in a language are two distinct concepts. C++ is in
some ways more expressive than C but not as expressive as Lisp (which is
a dynamically typed language). What's got one to do with the other?
 
K

kwikius

I don't quite understand that statement. What do you mean? Static typing
and expressiveness in a language are two distinct concepts. C++ is in
some ways more expressive than C but not as expressive as Lisp (which is
a dynamically typed language). What's got one to do with the other?

Wel heres my take on it.

If you have strong typing you can be more expressive in comfort
because errors in expressions will be caught by the compiler, whereas
dynamic typing postpones errors till runtime and it may take much
testing to try to locate all possible errors.

IOW the dynamic language is "expressive" of many things though some
are potentially incorrect, but the static typed language is
expressive, whilst being (arguably) proved correct prior to
execution.

regards
Andy Little
 
P

Pavel

kwikius said:
Wel heres my take on it.

If you have strong typing you can be more expressive in comfort
because errors in expressions will be caught by the compiler, whereas
dynamic typing postpones errors till runtime and it may take much
testing to try to locate all possible errors.

IOW the dynamic language is "expressive" of many things though some
are potentially incorrect, but the static typed language is
expressive, whilst being (arguably) proved correct prior to
execution.

regards
Andy Little

I am not sure one language is much more expressive than the other --
IMHO it is much more dependent on the style of use than the language
itself. I have seen quite understandable code in different Assemblers
and much more of inscrutable code in all possible languages even
including Python (although it is not too easy to write something
completely misleading in Python -- maybe only on purpose). But the "cost
of complete understanding" of a C++ program was always among the highest
for me -- often, I had to pre-process a source file to understand with
certainty what's coming from where. Consider this fragment:

int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with some
certainty that myprint() receives 0 as an argument. But to tell
something about it in C++ I have to know whether f() takes a reference
or a value and, to make things even more fun, I never know which of
possible overloaded f's is called, -- not until I pre-process the code
and line up all possible fs. IDE with a browser may help somewhat but as
it jumps to the definition or declaration of f() it dislocates my focus
-- quite an overkill especially if the only purpose of my review is to
track down where that 'i' could get changed.

To review C++ code with a reasonable speed (as compared to Java, C or
even PL/SQL code of the same functional complexity -- even FORTRAN), one
would have to put a lot of trust to the people who wrote it. I
personally got burned too many times and I do not trust anymore so I
have to bite the bullet and jump the sources back and forth like crazy.
Which brings us back to the productivity question.. it should not come
at a surprise that in a project of any considerable size a developer
spends more time reading, researching and understanding the code than
changing it. From this perspective, unexpectedly, C is so much more
productive than C++ (plus, an equivalent C program usually compiles 10
times faster than C++ -- because "smart guys" like inserting templates
and meta-programming wherever they don't need them or at least they will
include a couple of "cool" headers -- so a change/compile/debug
iteration in C is much shorter than in C++).

Not sure how to break this vicious cycle -- it seems the more powerful a
language is the more it gets abused and the more it hurts the
productivity. Java is getting there too, BTW, and C# is almost there
already (see version 3.0 of the language). I, for one, have never been
more productive than when I wrote in FORTRAN 66 in my University -- and
I can still easily read those subroutines after 25 years. I wish I could
say it of my C++ code after 25 years..

-Pavel
 
K

kwikius

Pavel wrote:
I am not sure one language is much more expressive than the other --
IMHO it is much more dependent on the style of use than the language
itself. I have seen quite understandable code in different Assemblers
and much more of inscrutable code in all possible languages even
including Python (although it is not too easy to write something
completely misleading in Python -- maybe only on purpose). But the "cost
of complete understanding" of a C++ program was always among the highest
for me -- often, I had to pre-process a source file to understand with
certainty what's coming from where. Consider this fragment:

int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with some
certainty that myprint() receives 0 as an argument. But to tell
something about it in C++ I have to know whether f() takes a reference
or a value and, to make things even more fun, I never know which of
possible overloaded f's is called, -- not until I pre-process the code
and line up all possible fs.

Deducing automatically which function to call based on its arguments is
certainly an important feature in making C++ what I would call
"expressive". Its obviously not available in C. (I cant remember if
there is an overloading scheme available in Java, but even if it is it
would be of limited use because Java is OOP and function overloading is
actually about expressions which are not part of the OOP vocabulary.
Note that Fortress Suns next generation language incorporates
overloading based on various constructs as well as many other familiar
general constructs that have been available in C++ for a long time)

I would prefer if the algorithm regarding which function is actually
called was more rigorously and concisely expressed itself. In general in
C++ you kind of hope that the expected version of a function will be
used, and thats arguably far from ideal (You can't blame C++ for its
complex and loose approach to overloading. C++ is essentially quite a
nice expressive language mixed up with C. The fact that its mixed with C
is AFAIK a major reason for its success, but also the source of many of
its problems (I think this is said somewhere by Bjarne Stroustrup)

In fact I am currently trying to find that simple algorithm regarding
expressions and their relation to types. Its important enough IMHO to be
basis of a whole language. Programming is essentially about writing
expressions. You want conciseness, intuitiveness and clarity with
generality. I am very grateful to C++ for showing me these things and
can now sit back in my armchair and see if and how to improve how C++
goes about it(but in another language, C++ is already seriously
overweight with new stuff) Standing on the giants shoulders and all
that. So can you have expressiveness, but also precision. C++ shows the
problem but not the full solution.

BTW. Note that in the example you gave, because the argument is an int
IOW an inbuilt type there are only a few functions that can be
called(unless you have brought in other namespaces!). If the argument is
a class (a user defined type or UDT) then the list grows large and if
the class involves templates the list grows even larger.

<...>

because "smart guys" like inserting templates
and meta-programming wherever they don't need them or at least they will
include a couple of "cool" headers -- so a change/compile/debug
iteration in C is much shorter than in C++).

Unfortunately I am one of those guys ;-)

http://sourceforge.net/projects/quan

I wouldnt be without quan. It heavily used everyday in my work (though I
dont maintain publicaly any more) and currently C++ is the only language
it can be written practically in.

Not sure how to break this vicious cycle -- it seems the more powerful a
language is the more it gets abused and the more it hurts the
productivity. Java is getting there too, BTW, and C# is almost there
already (see version 3.0 of the language). I, for one, have never been
more productive than when I wrote in FORTRAN 66 in my University -- and
I can still easily read those subroutines after 25 years. I wish I could
say it of my C++ code after 25 years..

Its an interesting problem. All succesful languages grow more complex. I
guess there is a solution, which is the one taken by Haskell... "Avoid
success at all costs". Its an enigmatic motto, but after many years I
finally understand it. I think its the best motto... if you want to stay
expressive ;-)

regards
Andy Little
 
B

Bo Persson

Pavel said:
I am not sure one language is much more expressive than the other --
IMHO it is much more dependent on the style of use than the language
itself. I have seen quite understandable code in different
Assemblers and much more of inscrutable code in all possible
languages even including Python (although it is not too easy to
write something completely misleading in Python -- maybe only on
purpose). But the "cost of complete understanding" of a C++ program
was always among the highest for me -- often, I had to pre-process
a source file to understand with certainty what's coming from
where. Consider this fragment:
int i = 0;
f(i);
myprint(i);

If it is written in Java (or C, for that matter), I can tell with
some certainty that myprint() receives 0 as an argument. But to tell
something about it in C++ I have to know whether f() takes a
reference or a value

Using a better name than f() would help a lot!

Hardly a language problem.
To review C++ code with a reasonable speed (as compared to Java, C
or even PL/SQL code of the same functional complexity -- even
FORTRAN), one would have to put a lot of trust to the people who
wrote it. I personally got burned too many times and I do not trust
anymore so I have to bite the bullet and jump the sources back and
forth like crazy. Which brings us back to the productivity
question.. it should not come at a surprise that in a project of
any considerable size a developer spends more time reading,
researching and understanding the code than changing it. From this
perspective, unexpectedly, C is so much more productive than C++
(plus, an equivalent C program usually compiles 10 times faster
than C++ -- because "smart guys" like inserting templates and
meta-programming wherever they don't need them or at least they
will include a couple of "cool" headers -- so a
change/compile/debug iteration in C is much shorter than in C++).

As usual, "You can write bad programs in any language".

Here is an example of what you can do in C
(http://www.ioccc.org/2004/hoyle.c), hardly 10 times easier to read
than anything else.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define _ ;double
#define void x,x
#define case(break,default) break[O]:default[O]:
#define switch(bool) ;for(;x<bool;
#define do(if,else) inIine(else)>int##if?
#define true (--void++)
#define false (++void--)

char*O=" <60>!?\\\n"_ doubIe[010]_ int0,int1 _ Iong=0 _ inIine(int
eIse){int
O1O=!O _ l=!O;for(;O1O<010;++O1O)l+=(O1O[doubIe]*pow(eIse,O1O));return
l;}int
main(int booI,char*eIse[]){int
I=1,x=-*O;if(eIse){for(;I<010+1;I++)I[doubIe-1]
=booI>I?atof(I[eIse]):!O
switch(*O)x++)abs(inIine(x))>Iong&&(Iong=abs(inIine(x
)));int1=Iong;main(-*O>>1,0);}else{if(booI<*O>>1){int0=int1;int1=int0-2*Iong/0
[O]switch(5[O]))putchar(x-*O?(int0>=inIine(x)&&do(1,x)do(0,true)do(0,false)
case(2,1)do(1,true)do(0,false)6[O]case(-3,6)do(0,false)6[O]-3[O]:do(1,false)
case(5,4)x?booI?0:6[O]:7[O])+*O:8[O]),x++;main(++booI,0);}}}

Bo Persson
 
J

James Kanze

Pavel wrote:
<...>

That's not preprocessing. Preprocessing is something else
entirely (which C++ inherits from C). And preprocessing is a
problem: if myprint (or f, for that matter) is a macro, who
knows what the above means.

One of the evolutions of C++ with respect to C is to reduce the
need for macros---good C++ makes very, very limited use of
macros. So you should have less problems with the above in C++
than in C.
Deducing automatically which function to call based on its
arguments is certainly an important feature in making C++ what
I would call "expressive".

Like everything which increases expressivity, it can be abused.
I'm tempted to say that if myprint is overloaded, and it matters
which instance of myprint is called, overloading has been
abused.

Of course, Pavel is right about one thing: the last line in the
above could be the declaration of a variable (which would be a
duplicate declaration, but if i were in some different scope, it
would be a legal declaration). IMHO, this goes beyond
"expressivity", and is frankly a defect. But it's one we
inherited from C, and the same ambiguity exists in C. (All
that's needed, in both cases, is that myprint is defined by a
typedef somewhere. And that's one ambiguity that isn't present
in Java.)
Its obviously not available in C.
(I cant remember if there is an overloading scheme available
in Java, but even if it is it would be of limited use because
Java is OOP and function overloading is actually about
expressions which are not part of the OOP vocabulary.

Never the less, Java's overloading is almost identical to that
of C++. If it's less of an issue, it's only because Java
doesn't support as many implicit conversions (another thing C++
has mainly because of C compatibility).
Note that Fortress Suns next generation language incorporates
overloading based on various constructs as well as many other
familiar general constructs that have been available in C++
for a long time)
I would prefer if the algorithm regarding which function is
actually called was more rigorously and concisely expressed
itself. In general in C++ you kind of hope that the expected
version of a function will be used, and thats arguably far
from ideal (You can't blame C++ for its complex and loose
approach to overloading. C++ is essentially quite a nice
expressive language mixed up with C. The fact that its mixed
with C is AFAIK a major reason for its success, but also the
source of many of its problems (I think this is said somewhere
by Bjarne Stroustrup)

I don't know if Stroustrup said it, but it's certainly true.
The biggest single problem in C++ is the declaration syntax,
which is inherited from C. To many implicit conversions
(especially lossy conversions) would be another inherited
problem. (And it's too many implicit conversions which makes
overload resolution so complicated.)
BTW. Note that in the example you gave, because the argument
is an int IOW an inbuilt type there are only a few functions
that can be called (unless you have brought in other
namespaces!).

Or you have classes which have non-explicit constructors which
take a single integral type.
If the argument is a class (a user defined type or UDT) then
the list grows large and if the class involves templates the
list grows even larger.

because "smart guys" like inserting templates

On the other hand, because of C++'s better type checking and
encapsulation, you normally need a lot less change/compile/debug
cycles than you would with C. Globally, development times in a
well run project are significantly less in C++ than in C (or in
Java, for that matter).

That's why you need a development process, and to pay attention
to software engineering issues. Good code review can do wonders
in this regard. Greater expressivity does allow more ways of
screwing things up, but it also allows more effective solutions.
The trick is to manage things so you get the benefits without
the costs.
 
J

James Kanze

Pavel wrote:
Using a better name than f() would help a lot!
Hardly a language problem.

Yes and no. It's only a fragment; let's expand it some:

int i = 0 ;

void
myFunction()
{
f( i ) ;
myprint( i ) ;
}

Now throw in a "typedef double myprint;" before the first line.
Rather changes things, don't you think?

No matter how you consider it, the declaration syntax of C is a
mistake. A mistake which C++ inherits. It's the price we pay
for C compatibility.
 
P

Pavel

James said:
That's not preprocessing. Preprocessing is something else
entirely (which C++ inherits from C). And preprocessing is a
problem: if myprint (or f, for that matter) is a macro, who
knows what the above means.
I am afraid I was not clear enough. No macros was assumed to be involved
in the above (see "*some* certainty" cited above). The actual point is
that in C++ you cannot say whether

void f(int i);
or
void f(int &i);

is called, without looking elsewhere and getting distracted by that (on
some platforms, the fastest way for me to say is to vi the output of the
preprocessor -- that's from where the reference to the p).

"Expressive" to me means something close to the opposite to having to go
to the reference (header file, browser window etc) to understand what
the "expressive expression" really does. You will probably agree that
the syntactic meaning of something as simple as " int i = 0; f(i);" is
supposed to become obvious without much effort -- if it is not, getting
to a comfortable level of understanding of a syntactic meaning of a
little bit less trivial piece of code is supposed to take infinite
amount of time by definition -- isn't it?
...
Of course, Pavel is right about one thing: the last line in the
above could be the declaration of a variable (which would be a
duplicate declaration, but if i were in some different scope, it
would be a legal declaration). IMHO, this goes beyond
"expressivity", and is frankly a defect. But it's one we
inherited from C, and the same ambiguity exists in C. (All
that's needed, in both cases, is that myprint is defined by a
typedef somewhere. And that's one ambiguity that isn't present
in Java.)
No I just meant that reference/value ambiguity, all other would be
explicit abuses and this one is a matter of course. Now everyone is
saying "use C++ references instead of C pointers wherever a pointer
cannot be NULL" but, mind you, in C you would have "f(&i);" vs "f(i);"
-- no ambiguous reading possible.
I don't know if Stroustrup said it, but it's certainly true.
The biggest single problem in C++ is the declaration syntax,
which is inherited from C. To many implicit conversions
(especially lossy conversions) would be another inherited
problem. (And it's too many implicit conversions which makes
overload resolution so complicated.)
Again, I should not have probably mentioned the overloading above as the
point was about the by-value vs by-reference call; but it does add
insult to injury by stealing more of my time in the situations like
above (something "expressiveness" is not supposed to do, IMHO).
On the other hand, because of C++'s better type checking and
encapsulation, you normally need a lot less change/compile/debug
cycles than you would with C. Globally, development times in a
well run project are significantly less in C++ than in C (or in
Java, for that matter).
Apparently your mileage differs from mine. Java became quite agile
(somewhere after 2000-2001 when major bugs were eliminated from
implementations) but in my experience C++ projects blew by far more
deadlines than FORTRAN, Assembler, C or Java (after the latter matured
with the adoption of 1.3.1 and 1.4) -- and some of the firms I worked
for were really well-run hardware/software shops. Of course I mean the
deadlines for commercial products, not some semi-working prototypes. To
summarize my experience: while you are writing in C++ everything is so
much faster and more expressive than in another language; as soon as the
tables are switched and you are on the reading side, the situation
changes drastically.

Also, you are completely out of control: be you even the best C++
programmer in the world but given some hundreds KLOC of C++ written by a
"C++ scholar" or, worse, a by bunch of those guys, each with his/her
"principles", you face a nice choice between never giving you manager
"the date" and guaranteed blowing it up. Remember, you are never
expected to re-write a significant part of the existing code, but only
to "quickly fix few little issues we have" and "add a couple of new
features the business wants delivered yesterday". Under these
circumstances, I prefer inheriting even FORTRAN code to inheriting C++
(with the additional bonus of receiving some extra time for changing
FORTRAN code to something more modern :) ). I guess, to be honest with
others, I have to leave to them the legacy I would be willing to inherit
myself, no matter how cool it feels to write "expressively".

...
That's why you need a development process, and to pay attention
to software engineering issues. Good code review can do wonders
in this regard. Greater expressivity does allow more ways of
screwing things up, but it also allows more effective solutions.
The trick is to manage things so you get the benefits without
the costs.
Yes, I have heard above this free cheese before -- but have never eaten
one :).

-Pavel
 
P

Pavel

Bo said:
Using a better name than f() would help a lot!
You are trying to avoid the point really hard -- I am clapping my hands!

Imagine you changed f() to doSomething() where Something really speaks
for itself. In C, you can just leave it at that, in C++ you have to say:

doSomethingAndNeverChangeTheArgument(i) or
doSomethingAndMaybeChangeTheArgument(i) to give the reader the same
level of understanding of just *syntactic meaning* of the code they
would otherwise have in C from simply doSomething(i). Note that the
issue has nothing to do with the topic of how well "Something"
represents the *business purpose* of the function, which IMHO is what it
should represent -- that's why I used f() in my example at the first
place, namely to avoid distracting my the reader's attention from the
*syntactic meaning* of which "the most expressive language" gives the
reader the vaguest idea in this example.

Please let me know if you have further questions about my example.
Hardly a language problem.
What is it then?
As usual, "You can write bad programs in any language".
....
No arguing here. I am not talking about writing programs by the way, I
am talking about the competition between the languages in wasting my
time when I am given a program I have to read and understand to some
comfortable level. From my 25-year experience C++ and Perl share 1st and
2nd place with bash and Korn-shell closely following.

I am not saying there is no good C++ programmers (and, by now, you
should have an idea what I mean by "good" -- it includes "not extra
expressive") -- but my mileage says there are more Python, C and Java
good programmers than C++. The language must have to do something with
this pure observation, don't you think so? Or would you argue my 25
years in the industry are statistically insignificant?

-Pavel
 
S

Stefan Ram

Pavel said:
In C, you can just leave it at that

It could still be implemented as a macro in C (as some
standard functions are, while still being spelled in lower
case letters). Such a macro could possibly modify the argument
object's value.

Also, »never change the argument« often is implied by the
name already.

For example, in:

sin( x )

, the reader will assume that »sin« means the trigonometric
function »sine« and that it will not change the value of any
object that happens to be the argument.
 
P

Pavel

Stefan said:
It could still be implemented as a macro in C (as some
standard functions are, while still being spelled in lower
case letters). Such a macro could possibly modify the argument
object's value.

Also, »never change the argument« often is implied by the
name already.
....
Thank you, but we are not talking about you or me -- we *never* write
code like this, do we? Essentially, you and me say same thing: you say
"you have to imply by the name", and I even give 2 good examples of such
names -- or were those examples bad?

We are talking about *some* honest and naive programmer who wrote it and
moved on and you and me are now bound to read his or her writing. My
point is exactly that, in C, he or she would not have to "imply by the
name" whereas in C++ -- yes, he or she had better do so. I guess this is
because C++ it is the most "expressive language", and I guess this is
the main feature of an expressive language -- to make a programmer to
write more words or else his or her reader is screwed -- as opposed to
the less expressive languages, that do not require such extra words. I
guess, wordiness is the new synonym for both expressiveness and
conciseness (just for the record -- the conciseness of C++ was referred
to by Andy before in this thread, so I am not trying to change a subject
here).

-Pavel
 
P

Pavel

Alf said:
* Pavel:

Please note that the above difference between C and C++, favoring C,
holds only for primitive types.

When you're passing an array, or when you're passing a structure in the
most common way in C (namely as a pointer), then in C89 you can't see
from the call site what the called function does, whether it modifies or
not.

However, in C++ you can easily see that at the call site: if the
argument is const, it will not be modified unless the function is a very
bad 'un.

Summing up, you're drawing an invalid and very misleading generalization
based on very incomplete knowledge of or familiarity with the languages
you compare.

It is very common though, one of those irrational memes just floating
around and picked up uncritically by scores of novices.

Alf,

As before, for some reason you try to get personal immediately. Try one
more time -- and I will tell you what I think of the critical thinking
skills of those who have read only one book, learned only one language
etc (of course, my flame will be as well based as your ridiculing my
experience and proficiency level in C++). For now, I will try to stick
to the subject.

Yes, my 25 years of programming experience (of them 19 in C++) may be
not too much, but I respected everybody else's experience -- I am just
saying that my mileage is this: understanding C++ code wasted most of my
time because I could never assume I understood from where the other guy
was coming. I tried assuming that and got burned -- I don't assume
anymore. I recognize that the others' mileage could differ and certainly
do not try to deny their experience.

You appear ready to dismiss an example which I have seen so many times
in the code used in production that I have gotten sick from it. To me
this dismissal comes from either denial (maybe you dismiss any example
that contradicts your theory as marginal or by denigrating other's
experience of by any other means it takes) or feeling entitled for
disrespecting the others for no obvious reason -- you pick the one.

I have never argued one could not write poorly supportable code in other
language than C++. I just said that by far most of such code I have
personally seen was written in C++ and suggested that others share their
experience and ideas of why they observed what they observed. I gave one
example -- the simplest one I could come up with, but certainly not the
only one I could give of when C++ code, even supposedly following "best
C++ practices (using references rather than pointers)" is more difficult
to understand than C or Java code. What's important is that this example
comes from repeatable real practice, not from my "intrinsic feeling of
what's right" or "how it should be" or "how it could be". I did not even
say I knew how this code should have been written -- this does not mean
I do not have an opinion on that but I am trying to refrain from
expressing opinions in favor of data analysis and I remind you that the
goal of this analysis is to come with a good guess what the future of
C++ is and why people think so.

If you have anything to say you are welcome to throw your *observations*
and please try to avoid generalizations and immediate conclusions (even
if they are your convictions). I will not denigrate your experience if
it contradicts mine -- at least you can be sure of that. Please notice I
have not thrown a single "generalization" into the discussion -- I have
always quoted the word "expressive" to emphasize it was not me who
brought it in. Therefore, I suggest you to recall you "misleading
generalization" language until it has a relevant target.

-Pavel
 
B

Bo Persson

Pavel said:
You are trying to avoid the point really hard -- I am clapping my
hands!

No, I am not. You say that from

f(i);

you cannot understand what f does, but from

f(&i);

it is suddenly obvuious. How?

My claim is that readable code looks like

sort(i);
increment(i);

which will obviosuly change the value of i, whether it is &i or just
plain i.

total_amount += i;

probably would not.



Bo Persson
 
J

James Kanze

I am afraid I was not clear enough. No macros was assumed to
be involved in the above (see "*some* certainty" cited above).
The actual point is that in C++ you cannot say whether
void f(int i);
or
void f(int &i);
is called, without looking elsewhere and getting distracted by
that.

But that's a false problem. Which one is called depends on the
semantics of the function, and you have to know that in order to
understand the code. And even if you know which of the above
actually corresponds, you still don't know the semantics.
(on some platforms, the fastest way for me to say is to vi the
output of the preprocessor -- that's from where the reference
to the p).
"Expressive" to me means something close to the opposite to
having to go to the reference (header file, browser window
etc) to understand what the "expressive expression" really
does. You will probably agree that the syntactic meaning of
something as simple as " int i = 0; f(i);" is supposed to
become obvious without much effort -- if it is not, getting to
a comfortable level of understanding of a syntactic meaning of
a little bit less trivial piece of code is supposed to take
infinite amount of time by definition -- isn't it?

Yes and no. What should be obvious without any effort is the
effect of the statement. Which depends on the semantics of the
function, and not just minor syntactic details. In well written
code, the name of the function will give enough information, and
in poorly written code, you're stuck. But that's true in just
about any language; I don't see where C++ causes additional
problems here.
Apparently your mileage differs from mine. Java became quite
agile (somewhere after 2000-2001 when major bugs were
eliminated from implementations) but in my experience C++
projects blew by far more deadlines than FORTRAN, Assembler, C
or Java (after the latter matured with the adoption of 1.3.1
and 1.4) -- and some of the firms I worked for were really
well-run hardware/software shops.

Apparently not.
Of course I mean the deadlines for commercial products, not
some semi-working prototypes.

That's interesting, because it is incredibly difficult to get
really robust Java. The language actually bans many of the
techniques which would help you here.

[...]
Yes, I have heard above this free cheese before -- but have
never eaten one :).

In other words, you've never actually worked in a place which
had a good software development process in place.

Don't blame the language when the problem is the environment.
 
J

James Kanze

Pavel said:
Bo Persson wrote:

[...]
You are trying to avoid the point really hard -- I am clapping my hands!

No he's not. He's addressing the real problem directly.
Imagine you changed f() to doSomething() where Something
really speaks for itself. In C, you can just leave it at that,
in C++ you have to say:
doSomethingAndNeverChangeTheArgument(i) or
doSomethingAndMaybeChangeTheArgument(i)

If you have to say that, then doSomething didn't speak for
itself. I've never used anything like
"AndMaybeChangeTheArgument" in the name of a function, and I've
never found readers of my code had any problem knowing which
functions modified their arguments, and which didn't. Even in
the standard library (which doesn't particularly shine by its
naming conventions), it seems rather obvious that v.insert()
will change the vector, and that v.size() won't. I don't need
to look and verify that size() is a const function, and insert()
isn't.

[...]
I am not saying there is no good C++ programmers (and, by now,
you should have an idea what I mean by "good" -- it includes
"not extra expressive") -- but my mileage says there are more
Python, C and Java good programmers than C++.

That's certainly not the case of Python (the total number of
Python programmers is probably less than the number of good C++
programmers), and almost certainly not for C. But it is, in
many ways, irrelevant. Supposing you meant the percentage of
good programmers, rather than the absolute number:

1. In my experience, there is a large group of bad programmers
who sell their wares by bluff. Because they're more
concerned with "marketing" than any technical issues, they
"practice" the most "in" language. I suspect that today,
they're mostly in C#; I've experienced them in Java and C++,
however, in the past.

C++ was very in at the beginning of the 1990's, and so
everyone and his bother was adding it to their CV. For
Java, the period was the end of the 1990's, but it may still
continue today---Java still enjoys great visibility. An
interesting effect is that when Java appeared, and became
the in language, the average skill of C++ programmers shot
up considerably.

But C++ is still fairly much in view, and there are still a
number of programmers claiming C++ skills who have
absolutely no competence in programming, in general, much
less in C++.

2. The percentage of good programmers will almost always be
greater in smaller languages, since the only people who are
using them are those who do so intentionally, and who know
enough to evaluate the various technical considerations.
I'm sure that the average level of programmers in Modula-3
is considerably higher than it is in C++, for example; all
five of them are really competent people.

3. While people at the end points (extremely skilled, or
incompetent) are exceptions, the apparent skill level of
most programmers depends on how well the software process is
run. I've worked in places with a well run process, and
I've seen very average programmers produce excellent code.
I've also works in poorly run shops, where even above
average programmers produced shit.

The language itself plays a role, but much less than you'd
imagine. Generally, it's been my experience that the success or
failure of a project never depends on the language; the cost of
making it a success can, to a certain degree, and C++ could
certainly be better. But in the well organized shops I've seen,
which have actually measured the difference, C++ turns out to be
less expensive than C (significantly) or Java (somewhat) in
terms of total programmer time needed. (This may depend
partially on the application domain. The place in question made
very, very large scale network management systems. I suspect
that the infrastructure available -- direct support in the
server, etc. -- might make Java cheaper for small, interactive
web sites. And infrastructure really should have been a fourth
point above---regardlesss of the intrinsic qualities of
Modula-3, for example, the lack of tools and support from other
products makes it a non-runner in most cases.)
The language must have to do something with this pure
observation, don't you think so? Or would you argue my 25
years in the industry are statistically insignificant?

Not knowing what you've been doing, who knows. Your experience
doesn't seem to correspond to mine (over 30 years), nor to
actual measurements made in the places I've worked.

Overall, my feeling is that nobody really likes C++, and that it
really isn't a very good language. But all of the others seem
to have even more problems, at least in general. (In specific
contexts, of course, the conclusion may vary.)
 
P

Pavel

Bo said:
No, I am not. You say that from

f(i);

you cannot understand what f does, but from
I don't know where you read this. I did not make any references to "what
f does" and it would be out of context. I said (and you cited it 10
lines above, but I guess I have to repeat it):

"If it is written in Java (or C, for that matter), I can tell with
some certainty that myprint() receives 0 as an argument. But to
tell something about it in C++ I have to know whether f() takes a
reference or a value".

The business purpose of f (sort, increment or whatever) is absolutely
irrelevant to the clarity of the *syntactic meaning* of the code.
Sometimes the well-chosen name may help one to make a better guess of
the syntactic meaning but this fact does not tell anything about the
qualities of the programming language as a communication tool: I could
select a self-describing name even in Assembler. Ok, in FORTRAN 66 I
would have to limit myself by 6 characters -- I will give you that, but
this does not apply to either C or Java. Namely because all other
languages allow the user to select good names, they are equivalent in
this regard, so I am factoring this out and use non-telling name 'f' to
attract attention to the fact that, with same name, Java gives a better
idea of how i is changing than C++.

Also, you have to really understand the purpose of code review. It is
not to evaluate how well the API is -- for that, you can review header
files in C/C++ or Javadoc in Java. It is only partially to evaluate the
compliance of the code to the coding standards -- because 70% of such
evaluation can be automated and another 20% (like the quality of in-line
documentation) will be clear from same header files and javadoc.

Most of the time when someone reviews the code, the purpose is to spot
most dangerous bugs that all unit/integration/system tests may have
missed because the whole data universe of most of real-world programs
cannot be, for practical purposes, completely covered by tests. If this
is the purpose of the code review (or if it is to find some bug that
already demonstrated itself), the meaning of any apparently telling name
must be a suspect. Namely, the code reviewer should get an unassuming
attitude and say, "ok, this function name is `doSomething()' but I
cannot take it for granted; let me see whether it really does *that*
something or it does something completely or subtly different even
though its original author meant it to do *that* something *and nothing
but that something*".
f(&i);

it is suddenly obvuious. How?

My claim is that readable code looks like

sort(i);
increment(i);

which will obviosuly change the value of i, whether it is &i or just
plain i.

total_amount += i;

probably would not.
Probably.. I wrote already how often I have been burned by such
assumptions. To know for sure, I have to see the prototype, and, if it
does take a reference, review the body... Not in C or Java.

Besides, even functions with telling names can (and often do) return
value in different ways. I will take your example:

compare:

int increment(int i) { return i + 1; } // #1

and

int increment(int &i) { return ++i; } // #2

I know, I know.. but people (not you and me of course :)) write things
like #2, sometimes for reason (of course on the hindsight and out of
context we are ready to blame them, but think of the standard C function
-- "time_t time(time_t *);" -- because it takes an old bad pointer,
nobody has any problem with it).

And obviously, with the possibility of the above 2 definitions, the
simple code

int i;
int j = increment(i);

poses very different different complexity to the reviewer of the C or
Java code, from one side, and C++, from another.


-Pavel
 
P

Pavel

James said:
Pavel said:
Bo Persson wrote:
[...]
int i = 0;
f(i);
myprint(i);
If it is written in Java (or C, for that matter), I can
tell with some certainty that myprint() receives 0 as an
argument. But to tell something about it in C++ I have to
know whether f() takes a reference or a value
Using a better name than f() would help a lot!
You are trying to avoid the point really hard -- I am clapping my hands!

No he's not. He's addressing the real problem directly.
Imagine you changed f() to doSomething() where Something
really speaks for itself. In C, you can just leave it at that,
in C++ you have to say:
doSomethingAndNeverChangeTheArgument(i) or
doSomethingAndMaybeChangeTheArgument(i)

If you have to say that, then doSomething didn't speak for
itself. I've never used anything like
"AndMaybeChangeTheArgument" in the name of a function, and I've
never found readers of my code had any problem knowing which
functions modified their arguments, and which didn't. Even in
the standard library (which doesn't particularly shine by its
naming conventions), it seems rather obvious that v.insert()
will change the vector, and that v.size() won't. I don't need
to look and verify that size() is a const function, and insert()
isn't.
Standard Library is a very bad example because it does have consistent
conventions and it is Standard, that is, a C++ programmer is expected to
know these conventions.

Any proprietary program of a considerable size is full of its own
conventions, most of the time they are little less consistent than in
the Standard (both because they have to cover bigger code base and their
authors did not have luxury of decades to polish these conventions).

Now can you please fix the code instead of only criticizing it? Bo gave
a good example:

int i = 0;
int j = increment(i);
cout << i << endl;

Please could you apply your vast experience of working in well-run
programming teams at which you hinted previously, and replace the
ill-selected names in this code to make it obvious for a reviewer what
line #3 is supposed to output without their having to resort to the
information outside of this original source code?

Oh, and yes -- what name choice would convince the reviewer that the
(renamed, of course) increment() function actually behaves with regard
to its argument exactly as its new perfect name unambiguously implies it
is supposed to behave?

-Pavel
[...]
I am not saying there is no good C++ programmers (and, by now,
you should have an idea what I mean by "good" -- it includes
"not extra expressive") -- but my mileage says there are more
Python, C and Java good programmers than C++.

That's certainly not the case of Python (the total number of
Python programmers is probably less than the number of good C++
programmers), and almost certainly not for C. But it is, in
many ways, irrelevant. Supposing you meant the percentage of
good programmers, rather than the absolute number:
Yes, that is what I meant.

I mostly agree with all that follows, but you introduced a lot of new
concepts, so I have some questions (see below):
1. In my experience, there is a large group of bad programmers
who sell their wares by bluff. Because they're more
concerned with "marketing" than any technical issues, they
"practice" the most "in" language. I suspect that today,
they're mostly in C#; I've experienced them in Java and C++,
however, in the past.

C++ was very in at the beginning of the 1990's, and so
everyone and his bother was adding it to their CV. For
Java, the period was the end of the 1990's, but it may still
continue today---Java still enjoys great visibility. An
interesting effect is that when Java appeared, and became
the in language, the average skill of C++ programmers shot
up considerably.

But C++ is still fairly much in view, and there are still a
number of programmers claiming C++ skills who have
absolutely no competence in programming, in general, much
less in C++.

2. The percentage of good programmers will almost always be
greater in smaller languages, since the only people who are
using them are those who do so intentionally, and who know
enough to evaluate the various technical considerations.
I'm sure that the average level of programmers in Modula-3
is considerably higher than it is in C++, for example; all
five of them are really competent people.
How do you define small vs big languages? From the above, it seems it is
by the number of practitioners; then, I would say, C++ is now fairly
small as comparing to Java; then, following your logic, reviewing Java
code must be, on average, more time-consuming and disappointing activity
than that of C++ code (per LOC or whatever other metrics) -- but my
experience tells different. But let me know if I guessed wrongly.
3. While people at the end points (extremely skilled, or
incompetent) are exceptions, the apparent skill level of
most programmers depends on how well the software process is
run. I've worked in places with a well run process, and
I've seen very average programmers produce excellent code.
I've also works in poorly run shops, where even above
average programmers produced shit.
Same experience -- but with some replaced epithets. No, I do not blame
you for s-word, I am just not sure we are thinking of the same issue. To
clarify, please could you classify the code like my snippet above
according to your standards you applied in the preceding paragraph --
whether it is, say, bad code in your opinion, and if it is, how would
you fix it.

(To be on record, here is my answer to this question: it is just the
code the like of which C++ (and C or Java) practitioners are likely to
meet in any development organization, no matter how run, that supports
large enough amounts of code. But their difficulties with this code will
differ depending on whether it is C++ or C or Java).
The language itself plays a role, but much less than you'd
imagine. Generally, it's been my experience that the success or
failure of a project never depends on the language; the cost of
making it a success can, to a certain degree, and C++ could
certainly be better. But in the well organized shops I've seen,
which have actually measured the difference, C++ turns out to be
less expensive than C (significantly) or Java (somewhat) in
terms of total programmer time needed. (This may depend
partially on the application domain. The place in question made
very, very large scale network management systems. I suspect
that the infrastructure available -- direct support in the
server, etc. -- might make Java cheaper for small, interactive
web sites. And infrastructure really should have been a fourth
point above---regardlesss of the intrinsic qualities of
Modula-3, for example, the lack of tools and support from other
products makes it a non-runner in most cases.)
Yes, of course, we are are talking about the languages that could be
used. Basically, C++ was unique in that it was the only [wide-spread]
language "with OOP" that could provide winning efficiency. I believe OOP
is useful for big project, BTW -- it takes some work to imitate them in
C although it is possible and was done successfully in those "poorly
run" development organizations I worked for. It required some
discipline, but probably less than C++ requires so those organizations
were not good enough for C++ (can't help it, sorry)

Java was very slow with exposing system level functionality and did not
perform too well for long time, so C++ was practically the only language
of choice for such apps. BUT -- this is changing very rapidly. (Just an
example, recently, I was able to write kind of a ps command in C# that I
could compile and run in both .Net and mono -- same code for both
Windows and Unix for ps! Anybody who ever tried to write ps-like utility
or API would really appreciate. It did not show much on UNIX (Mono API
is still not good enough), but my point is that the above advantage of
C++ is vanishing really fast. Java will have to take off their white
gloves to compete and will introduce more system-level abstractions
(they already started doing it, e.g. their Preferences API provides a
fair access to Windows registry -- it would be unthinkable "Java no-no"
in the 90s).

But my point is not about technical aspects of C++ -- it is quite
competitive in those, but about its communication aspects (I would use
the word "expressiveness" but it was already overused on this thread, I
think).

Basically, my concern is: will C++ keep enough practitioners to make it
safe for organizations to approve C++ for new programs (I am talking
about PMO programs, not computer programs here)? At some critical level,
they will just say: "Yes, you guys may be smarter than others, but we
cannot find as many smarties as we need and we learned hard way we can
only use the best for C++ specifically and it is too expensive to really
train them inside (as opposed for, say, Java or Python or C#) and you
are so expensive to both hire and fire (C++ legacy is a bigger liability
FORTRAN or C, from my experience) -- we are going to start this
application in Java (or even C) to reduce our risks of not finishing it
or not being able to fix or maintain it in the future". In fact, I have
been seeing it happening during the last 3-5 years (I have also ween
exceptions where organizations returned to C++ from Java but these were
just that -- rare exceptions, and these are now struggling with their
C++ projects).

Not knowing what you've been doing, who knows. Your experience
doesn't seem to correspond to mine (over 30 years), nor to
actual measurements made in the places I've worked.

Overall, my feeling is that nobody really likes C++, and that it
really isn't a very good language. But all of the others seem
to have even more problems, at least in general. (In specific
contexts, of course, the conclusion may vary.)

Hmm. I cannot recall another language where same piece of code can mean
so many different things depending on the non-local [from the reader's
perspective] context. My original example was the simplest one I could
come up with -- I don't even want to start on operator overloading etc.
I mean, it may not be the most popular feature these days, but this does
not help much while reviewing the others' code: who knows what the other
guy was thinking when he wrote this or that piece.

And the beauty of a preprocessor is a completely different song (C
shares the feature, but not Java or C#). I am all for pre-processors,
but the way it is done in C and C++ really hurts: you cannot tell a
difference between a macro and another object unless you rely on some
naming convention (and there are tons of evil articles around teaching
people how to make macros look and behave "just like functions" etc.).
One of IBM's PL/1 compilers had a much more powerful preprocessor, with
loops etc. but at least it was reasonable: all macro names started with
'%' so anybody could tell a macro from a non-macro without looking up
the definition..

-Pavel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Staff online

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,816
Latest member
SapanaCarpetStudio

Latest Threads

Top