Why do we have to manually separate interface and implementation?

P

Paul Fame

Hello World,

This is not a flame, but a question about the fundamentals of the
language. Unlike some languages, C++ requires class member functions
to be declared twice: once in the class declaration and again in the
definition. This is not too much of a pain for most simple classes but
I really hate the syntax for member functions of templated classes:

template<class A, class B, class C>
void ClassName<A, B, C>::FuncName() {}

You have to either do that for every method, or define all the methods
inline (looking at the MS STL implementation, it looks like they chose
the latter option even for some large functions).

Also, features like inline functions, const, and namespaces complicate
the issue further. My question is is there really an overall benefit
in having to do this, rather than have the interface extracted
automatically (eg. as in C# and Java). Is this necessity in C++
because of it's inheritance from C, or would the designers have put in
a proper module system if they were designing the language from
scratch?

- Paul
 
J

Jeff Schwab

Paul said:
Hello World,

This is not a flame, but a question about the fundamentals of the
language. Unlike some languages, C++ requires class member functions
to be declared twice: once in the class declaration and again in the
definition. This is not too much of a pain for most simple classes but
I really hate the syntax for member functions of templated classes:

template<class A, class B, class C>
void ClassName<A, B, C>::FuncName() {}

You have to either do that for every method, or define all the methods
inline (looking at the MS STL implementation, it looks like they chose
the latter option even for some large functions).

Also, features like inline functions, const, and namespaces complicate
the issue further. My question is is there really an overall benefit
in having to do this, rather than have the interface extracted
automatically (eg. as in C# and Java).

I don't know much about C#, but the interfaces are *not* extracted
automatically in Java.
Is this necessity in C++
because of it's inheritance from C,

No, it was added to benefit developers. In the version of C that
existed when C++ was first being written, you could use a function
without ever declaring it. The compiler will just assume the function
is defined in another module.
or would the designers have put in
a proper module system

In what way is a "proper module system" lacking?
if they were designing the language from scratch?

I highly doubt it, but that would be a good question for comp.lang.c++.

Keeping the interface separate from the implementation allows you to
concentrate on one, without regard for the other. C++ header files are
not just an implementation detail; they are a place to document your
module's interface.

If the typing really bothers you, I'm sure you could find a tool to
generate the interface files for you (something akin to javadoc). A
first pass search found this:

http://freshmeat.net/projects/makeheaders/?branch_id=6160&release_id=19953&topic_id=259,45

It looks a little outdated, but that's probably evidence of how little
it is needed.

Hth,
Jeff
 
J

Jeff Schwab

Jeff said:
I don't know much about C#, but the interfaces are *not* extracted
automatically in Java.



No, it was added to benefit developers. In the version of C that
existed when C++ was first being written, you could use a function
without ever declaring it. The compiler would just assume the function
was defined in another module.



In what way is a "proper module system" lacking?



I highly doubt it, but that would be a good question for comp.lang.c++.
:%s/lang/std/g


Keeping the interface separate from the implementation allows you to
concentrate on one, without regard for the other. C++ header files are
not just an implementation detail; they are a place to document your
module's interface.

If the typing really bothers you, I'm sure you could find a tool to
generate the interface files for you (something akin to javadoc). A
first pass search found this:

http://freshmeat.net/projects/makeheaders/?branch_id=6160&release_id=19953&topic_id=259,45


It looks a little outdated, but that's probably evidence of how little
it is needed.

Hth,
Jeff
 
P

Paul Fame

Hi,
I don't know much about C#, but the interfaces are *not* extracted
automatically in Java.

But in Java you don't have to duplicate function declarations and
definitions - you can define all your methods inline. (I dislike Java
compared to C++ for other reasons though).
In what way is a "proper module system" lacking?

Modules are done by textual inclusion. Any macros defined before the
#include can subtly modify the code in the included file. And then
there are the #pragma once or include guard kludges. Modules done by
textual inclusion often mean slower compiles than would be possible if
C++ had a proper module system.
Keeping the interface separate from the implementation allows you to
concentrate on one, without regard for the other. C++ header files are
not just an implementation detail; they are a place to document your
module's interface.

Glancing over the MS STL, the boost libraries, and several other
proprietary libraries, it seems they view header files as places to
put code when they couldn't be bothered typing it out in a separate
file. If you don't have a compiler that ignores this "inline"
suggestion, you will also find your object code bloated.

The C++ method is surely better than the C method of no argument
checking. Obviously it is too late for a change now... but I still
think a lot of the perceived complexity of C++ would disappear if you
didn't have to do this manual separation of interface and
implementation. Having worked in both Java and C++ for a while, I find
the former's method to be easier on code creation and maintenance.

- Paul
 
J

Jeff Schwab

Paul said:
But in Java you don't have to duplicate function declarations and
definitions - you can define all your methods inline. (I dislike Java
compared to C++ for other reasons though).


You can do the same thing in C++.

Modules are done by textual inclusion. Any macros defined before the
#include can subtly modify the code in the included file. And then
there are the #pragma once or include guard kludges. Modules done by
textual inclusion often mean slower compiles than would be possible if
C++ had a proper module system.


Thanks, now I see what you mean. The "include guards" really are a
kludge. According to Stroustrup, though, those are issues outside the
scope of the language definition. He predicted in _Design_&_Evolution_
(1994) that development environments would get much better, and that the
currently popular system of file inclusions eventually might go out of
vogue altogether. To some extent, he was right; the performance hit
that comes from textual inclusion is getting much less significant as
pre-compiled header compilation gains popularity. The Sun compiler has
been particularly good about this, and about sharing templates' object
code. Java handles much of this internally, in the same way that it
doubles as Make for small programs. It's really just a matter of where
you draw the line around what is (not) part of the language. Java is
clearly meant to be an entire platform; C++ is not.
Glancing over the MS STL, the boost libraries, and several other
proprietary libraries, it seems they view header files as places to
put code when they couldn't be bothered typing it out in a separate
file. If you don't have a compiler that ignores this "inline"
suggestion, you will also find your object code bloated.


I don't think those functions were inlined out of laziness. Actually,
that's a pretty funny (and somewhat insulting) assumption. :)

A huge chunk of the standard library is based on templates that must be
inlined. The fact is that the code bloat really isn't that bad. Of
course, there are systems that will page fault like mad on large object
files, but I think you'd have an uphill battle to argue that Java could
be squeezed into tighter spaces that C++.

The C++ method is surely better than the C method of no argument
checking.


That's the old C method. I believe C99 does require function
declarations with appropriate argument lists ( gurus please correct me ).

Obviously it is too late for a change now...


Nonsense. The bits you feel are lacking can always be provided by
compilers as enhancements, and popular enhancements are always great
candidates for additions to the standard. The enhancements have been
slow in coming because dissatisfaction with the current methodology has
been low.

but I still
think a lot of the perceived complexity of C++ would disappear if you
didn't have to do this manual separation of interface and
implementation.


Well, you don't have to do any such thing, but you do have a point.
Perhaps students should first be taught to define all methods inline,
then be taught the more traditional approach as an "advanced technique
for reducing object-file size."

Having worked in both Java and C++ for a while, I find
the former's method to be easier on code creation and maintenance.


Really? I haven't worked extensively with Java, but I have tried to use
it for pet projects. Anyway, I'm glad it works for you; I think the
platform is brilliant. I'd love to see a C++ compiler for the JavaVM,
but I'm not holding my breath.

-Jeff
 
P

Paul Fame

Hi,
You can do the same thing in C++.

But your code is then not compiled separately. And if you're unlucky,
your compiler will inline all the functions, causing massive code
bloat.
Thanks, now I see what you mean. The "include guards" really are a
kludge. According to Stroustrup, though, those are issues outside the
scope of the language definition. He predicted in _Design_&_Evolution_
(1994) that development environments would get much better, and that the
currently popular system of file inclusions eventually might go out of
vogue altogether. To some extent, he was right; the performance hit
that comes from textual inclusion is getting much less significant as
pre-compiled header compilation gains popularity.

Yeah. What I have been doing in my projects is making a single master
header that includes everything, and having every module include that
header. A strange way to organise software, but with precompiled
headers it makes it compile fastest.
I don't think those functions were inlined out of laziness. Actually,
that's a pretty funny (and somewhat insulting) assumption. :)

But the functions are often pretty large, and shouldn't have been
inlined. The only conclusion I can draw is that they (like me) don't
like the syntax for out-of-line methods of class templates.
A huge chunk of the standard library is based on templates that must be
inlined. The fact is that the code bloat really isn't that bad. Of
course, there are systems that will page fault like mad on large object
files, but I think you'd have an uphill battle to argue that Java could
be squeezed into tighter spaces that C++.

Agreed, Java is a memory and CPU hog. But my standards are high, as I
began programming on the Commodore 64, which fit a BASIC interpreter
into 8K, where every useful game or app was written in pure assembly
language, with dynamic memory a laughable concept. Now it saddens me
that I compile Hello World in MSVC++ and it churns out a 160KB
executable.

- Paul
 
V

Victor Bazarov

Paul Fame said:
But your code is then not compiled separately. And if you're unlucky,
your compiler will inline all the functions, causing massive code
bloat.

Nonsense. You can use pimpl idiom and compile them separately.

One thing you should probably remember: there is no free lunch. You
either have all your functions in one place or you have lean and very
well organised system.
[...] What I have been doing in my projects is making a single master
header that includes everything, and having every module include that
header. A strange way to organise software, but with precompiled
headers it makes it compile fastest.

Standard C++ does not define anything named "precompiled headers".
Keep that in mind :)
Agreed, Java is a memory and CPU hog. But my standards are high, as I
began programming on the Commodore 64, which fit a BASIC interpreter
into 8K, where every useful game or app was written in pure assembly
language, with dynamic memory a laughable concept. Now it saddens me
that I compile Hello World in MSVC++ and it churns out a 160KB
executable.

Well, don't blame the language, blame the compiler and library
creators.

See http://www.research.att.com/~bs/bs_faq.html#Hello-world (and
other questions and answers for more information).

Victor
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top