The worst things about C++

  • Thread starter Steven T. Hatton
  • Start date
O

Old Wolf

Steven said:
No, this is not a troll, and I am not promoting Java, C-flat, D, APL, Bash,
Mathematica, SML, or LISP. A college teacher recently posted to this
newsgroup regarding her observation that there has been a significant
decline in the number of students opting to take courses in C++.

Most C++ courses are utter dreck. In fact the course tutor is
usually not proficient in C++. This may account for the decline.
 
D

Duane Hebert

Evan said:
I think the poster knows that.. what Kai-Uwe is saying is that you
can't just write std::limits::min() for the minimum value generically.
Which means that if you have a template that takes a type T and you
need to find the minimum value T can take on, you can't do it
generically, because std::limits<T>::min won't give it to you in all
cases.

This was actually my comment, not Kai-Uwe. And yes I do
know that.
It makes generic programming harder, NOT determining the minimum FP
value harder.

I would prefer min() to always return min() and something like
::smallest() that would return what std::limits<double>::min() returns.
 
D

Duane Hebert

red floyd said:
I'm not sure this is a wart. Since since most floating reps (does the
Standard mandate IEEE-754?) use a separate sign bit, the minimum value
of a floating type is -std::limits<floating_point_type_t>::max().

The point is that finding the min value for a double requires
finding the max value and negating it.

-The function is different depending on the type.
-The idea that min() means something different
when talking about an int as opposed to a double is also confusing.

Sounds like a wart to me <g>
 
M

Mathias Gaunard

Steven said:
Cpp. Almost everything about it from its ugly syntax to its brutish
disregard for program structure have been problems for me. Reading code
with Cpp conditionals is often confusing because one must know and keep in
mind what conditions hold at compile time for the particular build we are
working with. It cuts up syntax without regard for program correctness.
It can lead to unexpected behavior which is not obvious because its
consequences are manifested between the time the code is seen by the
programmer and the time it is seen by the compiler. It can be used to
arbitrarily rearrange and redefine program components. Even the #include
mechanism can cause significant problems. For example when header guard
name collisions happen they lead to hard to understand errors for which the
compiler typically provides worse than useless diagnostics. Name
collisions among macros are also significantly problematic. And these are
just a few of the objections I have to Cpp usage.

The related issues of ODR subtleties, the exact nature of linkage and
translation units has been another source of significant confusion for me.
This also ties into the use of the #include mechanism of Cpp. But it goes
beyond that. The concept of a translation unit is not symbolically
represented in the language, but it plays a significant role in the
structure of a program. The meaning and implication of static and extern
have always been nebulous to me. Only recently have I really come to
understand them.

Though it is, to a large extent, outside the scope addressed by the
programming language itself, the issue of library linkage has also been a
significant source of trouble for me.

There is work being done in the standard to improve that.
It's called `plugins'.

The only aspect of the core language I really find problematic, and this is
far less significant than any of the above, is the syntax related to
pointers to functions, and the syntax related to passing references to
arrays. The latter is something that Stroustrup seems to have omitted
completely from TC++PL(SE).

The latter is heritage from C, unfortunetely.
You could use std::array instead of arrays which are so weird.

I see nothing really problematic with functions pointers though.
 
M

Mathias Gaunard

Kai-Uwe Bux said:
a) 8.3.5/5, in particular the rule about initialization of const references
and the fact that one cannot bind temporaries to non-const references.

That makes perfectly sense though.
Why should you be allowed to modify rvalues? To help hell break loose?


b) that typeid returns a by and large useless type_info object where it
could return a full-fledged type object that would allow for introspection
and allocation/construction of variables of that type.

To return useful information it would need to store them somewhere.


c) that I cannot overload the dot operator, e.g., so that I could have smart
references or _1.member_function() in lambda.

That could have been nice, indeed.
But no good way was thought of.

d) that C++ doesn't have virtual member templates.

This is not trivial to implement.
Implementors already had enough problems with export, so it is hard
asking for features needing collaborative work of both the compiler and
linker.


f) that the standard is worded according to the philosophy "when in doubt,
declare the behavior undefined".

You're confusing undefined and unspecified.
And it has nothing to do with doubts.

g) that the standard library components have too restrictive requirements,
e.g., list<T> requires the type T to be complete.

Variables should be perfectly workable upon declaration.
Since list<T> is a container of T's, T must be complete.

Recursive definitions do not really play well with this, indeed.

h) that there is no integral type or typedef guaranteed to be long enough to
hold a void*, and that there is no useful conversion to integral types for
function and member function pointers.

There is one in the next standard.

A) that there is no guarantee that one can derive from standard
container/iterator classes.

Of course you can.
It's just that members aren't virtual, so you can't do polymorphism with
them.


B) that signed integral types make virtually no useful guarantees, and that
std::limits does not provide enough information to work around that
problem.

C++ only allow three ways to represent signed integrals.

C) that there is no arbitrary precision / big integer class and no matrix /
tensor template in the standard.

Those are available in third party libraries.


D) that there is no window / gui support in the standard.

This is heavily platform specific.
 
S

Steven T. Hatton

Mathias said:
There is work being done in the standard to improve that.
It's called `plugins'.

I guess that's kind of like modules with some kind of abstract linking
specification?
The latter is heritage from C, unfortunetely.
You could use std::array instead of arrays which are so weird.

Is that the same as boost::array (which may also be std::tr1::array??)? I
often use them. The truth of the matter is, if properly used, passing
arrays by reference works rather nicely with some template applications.
I see nothing really problematic with functions pointers though.

I just find the syntax less than obvious, and when I've needed to write them
myself, I had to look up the syntax. Right now, I remember how they work
because I recently look at them. In 3 months, however, I may not remember.
But, as I say, that is way down on the list of problematic features.
 
S

Steven T. Hatton

Signal9 said:
If you dont like it you can start from scratch and build it from top to
bottom in C++... go try that in java (or wait you cant).

I have to agree that pointer to member syntax is goofy. OTOH, I rarely need
it, and it really does push the bounds of proper encapsulation. It's
probably a good thing that it's less than obvious.
I like C++ and Java but they have their own purposes and uses. Also if
you are new to the technology field and want to become a developer, you
need to learn many techniques and languages. Do not stop and sit with
one language and framework/platform, learn everything you can.

That works with many languages. I had a professor who told us that a
programmer with 20 years experience in C probably didn't learn anything new
about programming languages in the past 19 years. Such a person had "one
year of experience twenty times", as he put it. Our prof suggested a
person who has exposure to many different languages will be a far better
programmer than one who has focused on only one.

I will argue that a person with one solid year of learning and working with
C++ is (with very few exceptions) a novice who is just getting started.
Right now the three strongest skills that company's are looking for in
a dev is: C++ (still number one), Java and C#.

I had a bit of exposure to C++ back before templates were considered part of
the language. I learned C fairly easily. I took one course in C and read
K&R cover to cover in a few days. Java was also fairly easy to pick up.
When I decided to learn C++ in earnest, I thought it was going to be about
as hard as Java had been. ....
 
S

Steven T. Hatton

Tony said:
Or instead of being a consultant of technology, be someone that can
actually build something with it. With C++, rarely do you have to look
anywhere else. All the time spent learning other languages and stuff
doesn't make you as valuable as one who can apply it to some domain, like
scientific computing, graphics/games, OLTP etc. Do survey the other stuff,
but don't waste too much time trying to learn everything and become too
broad to apply anything "professionally". (Sure, I could learn German,
Spanish and Latin. But I find English more than adequate for my purposes
and I have better things to do!).

I don't claim any proficiency in the language, but I did find that learning
a bit of German improved my understanding of English considerably. There
are some advantages to knowing how things are done in other programming
languages. Sometimes the idioms are transferable, and sometimes you gain
an appreciation for what C++ (or whatever your primary language is) doesn't
provide, and learn ways to compensate for those limitations.

For me, I feel like I still have a lot to learn in C++. I believe I've been
exposed to every aspect of the language, but that doesn't come close to
meaning that I can use every aspect proficiently. My time is better spent
improving my C++ skills than trying to learn C#.
 
S

Steven T. Hatton

Steve said:
Seems to me that all the above issues -- Cpp, linkage, translation
units, extern, static -- are inherited from C. This has the dual
problem of (1) some aspects of these features being out of date, and
therefore not part of "good" C++, and (2) long-time C programmers
know intuitively how these things work, and so don't think much
about what problems they might cause for other programmers.

It really goes beyond knowing how Cpp works. At a certain point, any
sufficiently large project which is pasted together with a bunch of Cpp
directives and definitions will become a burden. Not only does Cpp confuse
me at times, it can confuse my tools (including Emacs). It limits the
ability to create tools that provide extensive contextual information to
the programmer, because the tools have to be able to second-guess the
values macros will take on in different situations.
This might again be an argument for learning C first.

It's not so much that Cpp was hard, in itself, to understand. What it does
to code is hard to understand.
BTW, I like C/C++'s concept of separate translation and linkage
between translation units. It's very strong in practice.

The problem really isn't the basic model. It's the 'invisibility' of it.
Things are going on behind the scenes which have no direct symbolic
representation, and lead to subtle and confusing consequences. The
situation with the const char[]s used as template parameters is a good
example.

One thing that probably made my learning experience a bit more difficult
than what most people go through is that I learned C++ on a linux box using
Emacs (and KDevelop). On a Windows box with VC++ I would probably not have
encountered many of the problems I met in trying to do everything "by
hand". I also have a tendency to use CVS builds of very thing. I'm
finally cured of doing that with GCC.
 
S

Steven T. Hatton

John said:
Perish the thought.

The reality is that C++ is likely to be obsolete long before there is any
chance of your list of desired changes being implemented.

Did I recommend any changes in the Standard?
The next version
of the standard is still years away and won't come close to addressing
your wish list.
The version after that, if there is one, will be another
10 years or so further on, and it's anyone's guess what changes might be
made. The computing environment will have changed beyond recognition
before there is any chance of the preprocessor being abolished.

So what is the point of endlessly banging on about what you don't like
about C++? Learn it, live with it, and get on with it --- or use some
other language.

Uh, I am investing my time in learning C++. If C++ is considered too
difficult to be worth learning, then people and projects will move to other
languages. That means my options become more limited.

The biggest problem with all of the features I mentioned is that many C++
programmers really don't care if they abuse them. They don't even
understand what that means.
 
N

Noah Roberts

Mathias said:
I see nothing really problematic with functions pointers though.

Man, you guys are spending way too much time on this...

There's nothing problematic about function pointers beyond not really
being able to interchange them. The new function object being added to
the standard is a much better abstraction. Unfortunately for the OP it
uses pounds upon pounds of template magic to do so.
 
R

red floyd

Evan said:
I think the poster knows that.. what Kai-Uwe is saying is that you
can't just write std::limits::min() for the minimum value generically.
Which means that if you have a template that takes a type T and you
need to find the minimum value T can take on, you can't do it
generically, because std::limits<T>::min won't give it to you in all
cases.

It makes generic programming harder, NOT determining the minimum FP
value harder.

Ah, now I see your (and Duane's) point. Good call. My mistake.
 
S

Steven T. Hatton

Noah said:
Man, you guys are spending way too much time on this...

There's nothing problematic about function pointers beyond not really
being able to interchange them. The new function object being added to
the standard is a much better abstraction.

Care to provide a reference to the proposal?
Unfortunately for the OP it uses pounds upon pounds of template magic to
do so.

Anything like what is describe in Chapter 22 of _C++ Templates: The Complete
Guide_? I have to confess I haven't studied it closely.
 
K

Kai-Uwe Bux

Mathias said:
That makes perfectly sense though.
Why should you be allowed to modify rvalues?

You can already call a non-const member function of a temporary.
To help hell break loose?

No, but, e.g., to make working with proxy classes easier. Also, I just find
it silly that I can do

std::vector<int>().swap( some_int_vector );

but neither

std::swap( std::vector<int>(), some_int_vector );

nor

some_int_vector.swap( std::vector<int>() );

_Modifying_ temporaries is perfectly fine. I do it all the time. Hell does
not break loose. I do not see why _binding_ temporaries to non const
references is not fine. (I agree that there is a problem that arises from
temporaries created by automatic type conversion/promotion.)

To return useful information it would need to store them somewhere.

True. However, this information could be optimized away by the compiler if
global data flow analysis reveals that it's not used anywhere in the
compilation unit.

That could have been nice, indeed.
But no good way was thought of.

Sad but true.

This is not trivial to implement.
Implementors already had enough problems with export, so it is hard
asking for features needing collaborative work of both the compiler and
linker.

I know, it's tricky. Nonetheless, I'd love to have them.

You're confusing undefined and unspecified.

I don't think so.
And it has nothing to do with doubts.

That, maybe.

Variables should be perfectly workable upon declaration.
Since list<T> is a container of T's, T must be complete.

Recursive definitions do not really play well with this, indeed.

Well, the following compiles and works as expected with g++ (and I would
predict with most STL implementation):

#include <iostream>
#include <iterator>
#include <algorithm>
#include <list>

class recursive_list {

std::list< recursive_list > the_list;

public:

friend
std::eek:stream & operator<< ( std::eek:stream & o_str,
recursive_list const & rl ) {
if ( rl.the_list.empty() ) {
o_str << "[]";
} else {
o_str << "[ ";
std::copy ( rl.the_list.begin(),
rl.the_list.end(),
std::eek:stream_iterator<recursive_list>
( std::cout, " " ) );
o_str << "]";
}
return ( o_str );
}

void push_back ( recursive_list const & rl ) {
the_list.push_back( rl );
}

};

int main ( void ) {
recursive_list const empty_list;
recursive_list r1;
r1.push_back( empty_list );
r1.push_back( empty_list );
r1.push_back( empty_list );
r1.push_back( r1 );
r1.push_back( empty_list );
r1.push_back( empty_list );
r1.push_back( empty_list );
std::cout << r1 << '\n';
}

Intended output: [ [] [] [] [ [] [] [] ] [] [] [] ]

So it is possible (and already usual) to implement std::list<> the way I
would like. However, the code above has undefined behavior according to the
standard and is not even required to compile (but is permitted to): and
indeed, the code fails to compile when I build g++ with concept_checks
enabled.

There is one in the next standard.

That's good to know.

Of course you can.
It's just that members aren't virtual, so you can't do polymorphism with
them.

You can in all implementations that I have seen so far, yet there is no
guarantee in the standard. The type std::vector<T>::iterator is marked as
implementation defined: (a) it could be T* or (b) it could use a virtual
base trick to prevent derivation. At least the second point goes for all
iterator types. With regard to the container classes, I might be paranoid
in thinking that they could legally prevent derivation.

C++ only allow three ways to represent signed integrals.

Really? I recall that I once tried to deduce that from the standard and
that I failed.

Those are available in third party libraries.

True. However, this kind of thing can benefit tremendously from support by
compiler magic. In addition, standardization has more benefits that
providing availability. Anyway, the availability of third party libraries
makes this a minor nuisance, and I have already qualified this item as
such.

This is heavily platform specific.

So is IO. Yet still, the standard provides means for IO. Again, this is a
minor nuisance, and I might be argued that C++ could drop IO facilities
from the standard altogether.


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

Steven said:
Care to provide a reference to the proposal?

TR1 section 3, in particular 3.7 (polymorphic function wrappers).

Anything like what is describe in Chapter 22 of _C++ Templates: The
Complete Guide_? I have to confess I haven't studied it closely.

tr1::function< some_function_call_signature > is a class that can hold any
entity that you can use as the function object in a function call
conforming to the specified signature. I don't know whether what is in
chapter 22 conforms to that description.

Here is a baby version for unary functions just to demonstrate the kind of
combination of virtual functions and templates that goes into wrappers like
this:

template < typename R, typename T >
class unary_function_wrapper;

template < typename R, typename T >
void swap ( unary_function_wrapper<R,T> & a,
unary_function_wrapper<R,T> & b ) {
kubux::swap( a.f_ptr, b.f_ptr );
}

template < typename R, typename T >
class unary_function_wrapper
: public std::unary_function< R, T >
{

friend
void swap<> ( unary_function_wrapper &, unary_function_wrapper & );

struct base
: public std::unary_function< R, T >
{

virtual
T operator() ( R ) = 0;

virtual
~base ( void ) {}

virtual
base* clone ( void ) const = 0;

}; // unary_function_wrapper_base

template < typename F >
struct X : public base {

F f;

X ( F g )
: f ( g )
{}

virtual
T operator() ( R r ) {
return ( f(r) );
}

virtual
X* clone ( void ) const {
return ( new X ( f ) );
}

}; // X

base * f_ptr;

public:

template < typename F >
unary_function_wrapper ( F f )
: f_ptr ( new X<F> ( f ) )
{}

unary_function_wrapper ( unary_function_wrapper const & other )
: f_ptr( other.f_ptr->clone() )
{}

unary_function_wrapper & operator=
( unary_function_wrapper const & other ) {
unary_function_wrapper dummy ( other );
swap( *this, dummy );
return ( *this );
}

~unary_function_wrapper ( void ) {
delete ( f_ptr );
}

T operator() ( R r ) {
return ( (*f_ptr)( r ) );
}

}; // unary_function_wrapper


Now, unary_function_wrapper< int, void > can take any object x that can be
called like x(5) and returns void.


Best

Kai-Uwe Bux
 
J

John Carson

Steven T. Hatton said:
Uh, I am investing my time in learning C++. If C++ is considered too
difficult to be worth learning, then people and projects will move to
other languages. That means my options become more limited.

And posting about the problems with the precompiler and C++'s compilation
model is going to change that?
The biggest problem with all of the features I mentioned is that many
C++ programmers really don't care if they abuse them. They don't even
understand what that means.

So you hope to improve programming practices in this respect. This will mean
C++ is not considered as difficult to learn and so your options will be
broader. Talk about drawing a long bow!!!!!!!!

Save yourself the trouble and focus your energies on improving your C++
expertise. It will do far more to broaden your options.
 
S

Signal9

Tony said:
Or instead of being a consultant of technology, be someone that can actually
build something with it. With C++, rarely do you have to look anywhere else.
All the time spent learning other languages and stuff doesn't make you as
valuable as one who can apply it to some domain, like scientific computing,
graphics/games, OLTP etc. Do survey the other stuff, but don't waste too
much time trying to learn everything and become too broad to apply anything
"professionally". (Sure, I could learn German, Spanish and Latin. But I find
English more than adequate for my purposes and I have better things to do!).

Tony


and you will be on the corner asking for change when they drop the only
tool you know how to use....

i got 25cents for ya...
 
S

Steven T. Hatton

John said:
And posting about the problems with the precompiler and C++'s compilation
model is going to change that?

I've seen a lot of changes take place as a result such observations. One
high-profile project I know of completely reworked their Cpp laden code
base, replacing their macros with templates.
So you hope to improve programming practices in this respect. This will
mean C++ is not considered as difficult to learn and so your options will
be broader. Talk about drawing a long bow!!!!!!!!

Some people do listen to reason.
Save yourself the trouble and focus your energies on improving your C++
expertise. It will do far more to broaden your options.

I would still have to deal with crappy code if I only worried about my own
coding style. It is invariably the case that the design choices other
people make impact my ability to use appropriate language features when
extending their work.
 
S

Signal9

If you invest your time in this language it will not steer you wrong.
Honestly I would say learn this as your major language, but also learn
other languages. Java and C# are very popular right now and have a
decent mature framework.

When you start as a professional developer you will end up changing
languages over the years and maybe on a project to project basis
(depending on the company you work for).

Actually I say this to you. Go learn C++ as much as possible, learn C
as well. Then for "fun" develop your own high level language. this
will teach you a lot. At this point you may want to get into some
Assembly (which is heavily used in driver and kernel development).

The world of software development is fun, do not forget that. So go
have fun !
 

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

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top