Applications of C++

  • Thread starter magnus.moraberg
  • Start date
P

Pascal J. Bourguignon

James Kanze said:
James Kanze said:
(e-mail address removed) wrote:
[...]
One place C++ falls down badly is for run-time
metaprogramming. I have yet to find a good solution for
this. Java seems to offer the most popular compromise
between static typing and run-time introspection
("reflection"), if not outright metaprogramming. Lisp and
Smalltalk both seem to have better support, but lack
popularity in industry, possibly because they lack static
typing.
Exactly. It's a question of reliability: the more errors
that can be caught by the compiler, the less escape into the
actual program. I work mainly on systems where high
reliability is important. For those, even Java is too
"dynamic", and C++ (or Ada 95) seem to be about right. Note
that the size of the application is an issue as well. The
more people collaborating on the coding, the more static
checking becomes important as well.
I think there's a conceptual error in thinking that the
compiler will help catch the errors that matter.

All errors matter. And an error caught by the compiler costs
significantly less to correct than one caught by unit tests, or
even one caught by code review.

Well of course. But I meant to dismiss errors that are signaled by a
compiler that would not be errors with a more dynamic language.
 
S

SG

As you say, the code isn't doing the same thing.  For very small
programs (up to, say, 500 lines of code), yes.  C++ is more
verbose than, say, AWK or Python.  And in fact, for such things,
I use AWK, and not C++.  For larger projects, however, the
"verbosity" of C++ fulfills an important function---keeping the
interface specification separate from the implementation code.
While I think C++ is probably a little more verbose than Ada 95,
I don't think that the difference is significant.  And I don't
know of any other language which provides comparable features,
and which could really be used for the sort of projects C++
would typically be used for.

Regarding separating interface from implementation (.hpp/.cpp): The
Java folks don't seem to have a problem with the lack of header files.
They can write "interface XXX {...}" and/or just let the javadoc tool
generate some nice HTML documentation from the source code.

Cheers!
SG
 
B

Bo Persson

Jeff said:
I rarely bother with such separation in my own code; in fact, I
usually consider it a mistake. James and I have had this
discussion here before, though, and I have no interest in poking
that particular sleeping dog.

Why not?

Discussing why interface and implementation is so much better than
header and implementation, sounds fun. :)


Bo Persson
 
W

woodbrian77

Ho ho ho. :)

If you write lots of small classes and functions, then maintaining
separate declarations and definitions causes an absurd amount of source
code bloat (nearly 2x).  There is also the maintenance headache of
keeping function signatures up to date.  For high-level interfaces,
there's no problem, because the interfaces are meant to be stable;
arguably, changes to the overall interface of an application ought to be
difficult.  If the guts of your code include tons of tiny functions,
though, then making changes ought to be easy, not hard.  For example, I
vastly prefer this:

     template<class Coordinate>
     class point
     {
        Coordinate m_x;
        Coordinate m_y;
     public:

        typedef Coordinate coordinate;

        point(coordinate x, coordinate y )
          : m_x( x )
          , m_y( y ) { }

        coordinate x() const {
            return m_x;
        }

        coordinate y() const {
            return m_y;
        }
     };

To that:

     template<class Coordinate>
     class point
     {
        Coordinate m_x;
        Coordinate m_y;
     public:

        typedef Coordinate coordinate;

        point(coordinate x, coordinate y );

        coordinate x() const;

        coordinate y() const;
     };

     template<class Coordinate>
     point<Coordinate>::point(coordinate x, coordinate y)
       : m_x( x )
       , m_y( y ) { }

     template<class Coordinate>
     typename point<Coordinate>::coordinate
     point<Coordinate>::x() const {
         return m_x;
     }

     template<class Coordinate>
     typename point<Coordinate>::coordinate
     point<Coordinate>::y() const {
         return m_y;
     }

This is, of course, an extremely simple case.  In practice, the mess is
far worse.- Hide quoted text -


I tend to agree with you, but am glad that C++ permits both forms.
From a code generation perspective, being able to keep hand-written
interfaces separate from computer-written implementations is helpful
It would be a headache for me if I were trying to add computer-
written code to a file that had hand-written code. I wonder if
there are some Java developers out there who attempt that.

Brian Wood
Ebenezer Enterprises
www.webEbenezer.net
 
J

James Kanze

The point is that "headers" are the C++ way of specifying an
interface. One of the worst ways ever invented, but still
better than nothing.
If you write lots of small classes and functions, then
maintaining separate declarations and definitions causes an
absurd amount of source code bloat (nearly 2x). There is also
the maintenance headache of keeping function signatures up to
date.

There are tools that can help. But the point is that it should
require a significant amount of work to change the signature of
a function. Changing the signature breaks client code, and
shouldn't be done lightly.
For high-level interfaces, there's no problem, because the
interfaces are meant to be stable; arguably, changes to the
overall interface of an application ought to be difficult.
Exactly.

If the guts of your code include tons of tiny functions,
though, then making changes ought to be easy, not hard.

There's no way you can avoid having to modify client code. If a
function is used in a hundred different places in client code,
you have to modify a hundred different places in your code base
anytime you change it. That's a lot of work at the coding
level, and in anything but the smallest projects, it also
involves significant manageerial work, in order to synchronize
the changes (in different groups).

Obviously, this only applies to classes and functions which are
"exported"---made available to client code. For classes which
are private, the only real argument for not putting the function
bodies in the class is readability, and that really doesn't
apply if the classes and the functions are simple enough. And
of course, for the most private classes, those with block scope,
you don't have a choice anyway.
For
example, I vastly prefer this:
template<class Coordinate>
class point
{
Coordinate m_x;
Coordinate m_y;
public:
typedef Coordinate coordinate;
point(coordinate x, coordinate y )
: m_x( x )
, m_y( y ) { }
coordinate x() const {
return m_x;
}
coordinate y() const {
return m_y;
}
};
template<class Coordinate>
class point
{
Coordinate m_x;
Coordinate m_y;
public:
typedef Coordinate coordinate;
point(coordinate x, coordinate y );
coordinate x() const;
coordinate y() const;
};
template<class Coordinate>
point<Coordinate>::point(coordinate x, coordinate y)
: m_x( x )
, m_y( y ) { }
template<class Coordinate>
typename point<Coordinate>::coordinate
point<Coordinate>::x() const {
return m_x;
}
template<class Coordinate>
typename point<Coordinate>::coordinate
point<Coordinate>::y() const {
return m_y;
}

Templates are a bit tricky, unless you have a compiler which
supports export. What I'd really prefer is the second, but with
the template exported, and the function definitions in another
file, which isn't visible to the client.
This is, of course, an extremely simple case. In practice,
the mess is far worse.

Rather, this is an extremely simple case, where your solution
works (the class is really nothing more than a struct anyway).
But your solution doesn't scale.

In fact, of course, a lot depends on context. In some of the
more basic modules I write, where templates are involved, I'll
use a mixture. At the application level, however, anything that
is exported will not contain the implementation in a header
file.
 
N

Noah Roberts

Jeff said:
Ho ho ho. :)

If you write lots of small classes and functions, then maintaining
separate declarations and definitions causes an absurd amount of source
code bloat (nearly 2x).

I often purposfully set it up so that I can write entire sets of classes
within cpp files only. The "interface" of the class in these cases is
already defined as an abstract base in a header. Then I simply have to
add a way to register the class with a factory of some sort upon program
startup, usually with a "bool register()" and some macros so I'm not
writing "namespace { bool b = factory::register(new object); }" all the
time.

It's a misnomer to assume that every class has its own public interface.
Some simply implement one that is shared by many others.

When the class being implemented does have a public interface of its own
though, I usually do separate it into cpp and h files unless it's some
sort of utility file I want to have as header only.
 
J

Jorgen Grahn

On 5 mai, 22:46, (e-mail address removed) wrote: ....

I don't think I have heard RTTI and exceptions being accused of
causing code bloat before. People usually complain about the standard
containers and iostreams.
The C++ compilers for embedded system I have seen (IAR, and ARMCC)
don't implement RTTI and exceptions. There isn't ostream as well and
if there was, I suppose the codecvt would be removed since it tends to
bloat the code.

But keep in mind that "embedded systems" often translates to "a
full-blown computer running Linux, but with a bit of flash memory
instead of disk" these days. Some people call it "embedded" as soon
as there is custom hardware involved -- even if there are gigabytes of
RAM and disk, and a few hundred CPUs, and it runs Unix.

GCC rules in that market, of course.

/Jorgen
 
J

James Kanze

I don't think I have heard RTTI and exceptions being accused
of causing code bloat before. People usually complain about
the standard containers and iostreams.

Exceptions do tend to increase code size considerably, at least
with the most efficient implementations. (On the other hand,
I've not found std::vector making my programs any bigger than
they would have been otherwise.)
But keep in mind that "embedded systems" often translates to
"a full-blown computer running Linux, but with a bit of flash
memory instead of disk" these days. Some people call it
"embedded" as soon as there is custom hardware involved --
even if there are gigabytes of RAM and disk, and a few hundred
CPUs, and it runs Unix.

There are many different levels of "embedded": I've worked on
"embedded" systems which ran on a Sun Sparc, under Solaris, with
a moderate sized disk. I've also worked on embedded systems
with only 64 bytes of RAM and 2 KBytes of ROM. On the first, we
used full C++, with all the bells and whistles the compiler
supported at the time. On the second, we used assembler---even
C resulted in too much code bloat (or rather, too much RAM being
used).
GCC rules in that market, of course.

Or the native C++ of the platform. (I've seen more HP CC and
Sun CC than G++ in this field.)
 
B

Balog Pal

Actually, C still seems to hold sway there, although I can't
figure out why.

Because the compiler coverage is still weak. I thought in 2009 this can't be
the case but it is... :(

I.e. I currently make a project on PIC24 family, that have only 4 compilers
at all, 3 C and only one having C++. The last one starts at some 2000 GBP
and doubtful evaluation...
While the chip is pretty low on resources (like it has 16K ram in all, for
everything).

Going back to C is a pain in the ass, but buying in the monopoly did not
seem feasible.

Too bad we don't have some really standalone C++ -> C converter, I would
definitely use that for some portions. (I checked out Cameau they reserve
any custiom tailoring, and do not allow intermediate files of stock version
used like that...)

The 'native' compiler for the chip by MPLAB is based on gcc, I don't really
get why then it can't have C++ too either directly or indirectly -- but that
is the case. (unless I missed something on the road).
 
T

Tony

James said:
The point is that "headers" are the C++ way of specifying an
interface.

I would say that headers are the C way and that pure ABCs are the C++ way.
 
T

Tony

James said:
It would probably be easier to list areas where it isn't used;
almost all large scale applications today are developed in C++.
I work mainly on large scale servers, where C++ is really the
only language used... except for one case of Cobol that I'm
familiar with. At the other end, it's also used for a
considerable amount of system programming, although for
historical reasons, C still sees a lot of use there as well. It
shows up a lot in larger real time systems: telephone routing
and such.

However: if you're working for a masters, you probably shouldn't
worry about the language. In fact, you should learn several,
with different paradigms: at least one functional language, C++,
but probably also Java, probably at least one assembler, and
certainly some smaller, scripting languages.

But he said he wanted a Masters in C++. Maybe he wants to actually do
something with the language instead of becoming a language lawyer.
 
B

Bo Persson

Tony said:
I would say that headers are the C way and that pure ABCs are the
C++ way.

No, ABCs are the OO fundamentalist way - everything is dynamically
allocated, polymorphic, and all functions are virtual?

C++ doesn't stop you from doing that, but it isn't a good way to use
C++.


Bo Persson
 
T

Tony

Bo said:
No, ABCs are the OO fundamentalist way

Do I note a bit of agenda in your tone? C'mon, say what you really want to.
- everything is dynamically
allocated, polymorphic, and all functions are virtual?

Use of interfaces (aka, pure ABCs) doesn't mean that at all.
C++ doesn't stop you from doing that, but it isn't a good way to use
C++.

Ha!
 
J

joshuamaurice

Do I note a bit of agenda in your tone? C'mon, say what you really want to.


Use of interfaces (aka, pure ABCs) doesn't mean that at all.


Ha!

For example, the STL. I would consider it a (mostly) excellent
interface to useful libraries. There is little to no virtual in it,
and basically no abstract base classes either. OO is cool, but virtual
functions, runtime dynamic dispatch, class inheritance, etc., is not
always the best way to solve something.

Sometimes you don't want an implementation class, and a factory;
sometimes you just want a concrete class. Maybe for runtime
efficiency. Maybe for for sanity.

For example, I once saw some production code where OO took over and
ran amok. For some editor class, it had:
- An interface X
- an impl Ximpl
- an interface and impl class for every function in X to implement the
named parameter idiom.
- a factory for every single impl class.

It should have been one concrete top level class, and maybe a concrete
nested inner class per function for the named parameter idiom. Their
use of "good OO" was total overkill. It more than 4x'd the lines of
code for basically no good reason, adding maintenance cost and runtime
cost.

(Their argument was that it was to allow mocking the implementations
for unit testing. I called bull on that. Each class was only ~200
lines. There was no good reason to mock it. You could thoroughly test
it as is, and it's simple and concrete enough that mocking it to test
other components in unit tests is overkill. Way too much developer
time wasted when writing simple acceptance tests without mock would
have actually had higher coverage. PS: To this day, they haven't
actually mocked it to write those unit tests.)
 

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

Forum statistics

Threads
474,159
Messages
2,570,881
Members
47,418
Latest member
NoellaXku

Latest Threads

Top