Re: Header Files and Interfaces Yet Again

From: Steven T. Hatton (susudata_at_setidava.kushan.aa)
Date: 06/11/04


Date: Fri, 11 Jun 2004 08:01:52 -0400

Kai-Uwe Bux wrote:

> Hi,
>
>
> Steven T. Hatton wrote:
>> I have to confess, I am a bit confused by all of this. If I have a
>> library with compiled code, I can use the declarations in the headers to
>> compile my source, and I don't need to know about the 'definitions' until
>> I call the
>> linker. Or so I believe. I am under the impression that what the
>> declarations provide me with are the names needed to communicate to the
>> linker what needs to be connected to what. So if the declarations in
>> your "fake" headers have "real" names in the form that the declarations
>> would appear, I don't understand why they would not suffice as real
>> headers to feed to the compiler.
>
 
> As you can see, it contains way more information:
>
> a) it gives away implementation details as it has to list private fields
> and their types.
 
> b) it includes other headers, among them even those only needed in the
> private part of the class.
>
> The point that I hope to get across is that header files need to provide
> information to the compiler that is of no concern to the programmer using
> the library. Private fields of classes are of no concern whatsoever to the
> user. Nonetheless, a compiler has to know about them at compile time.
> Therefore, fake headers can not serve as sufficient information to the
> compiler.

They don't need to. Stroustrups approach is very similar to what you are
doing. But he actually uses what you call a fake header. There is no rule
against having multiple declarations appear in the same translation unit.
I'm not really srue why header files that present things that aren't
necessary for the client's code should need to be #included in the client's
source file. They should be #included in your source files. What you are
calling the fake header should be #included in the client's source.
Stroustrup even #includes the equivilaent in the implementation's header to
test it for consistency.
 
> There are more complicated examples involving templates, where it actually
> can be usefull or even necessary to give implemting code in the header
> files: after all template definitions need to be known at compile time. In
> those cases, the header file will be cluttered with implemtation details.
> A fake header will still be small and easy to read. But this is possible
> precisely because it does not need to contain all the information that the
> compiler needs to instanciate templates or allocate memory for private
> fields in classes.

I'm pretty sure you can treat templates in much the same way as regular
source is treated. I'm still learning about templates, so there may be
significant exceptions to this.
 
>> Stroustrup clearly provides a notion of having two (or more) sets of
>> functional headers. One set might be accessed by the user of a
>> component,
>> while another would be accessed by its implementor. Perhaps I'm missing
>> something but it appears to me the Standard Library is not designed
>> according to the guidelines presented in TC++PL(SE).
>
> I do not onw a copy of TC++PL(SE) so I cannot comment on this particular
> assesment. However, why would it be necessary, better, or advisable that
> the standard follows the guidlines in that book?

One reason is that the guidelines prescribe good programming practices.
Another reason is to maintain a consistent approach that will match the
reasonable expectations of people who learn C++ from the most authoritative
source available.
   
>> Interestingly the Standard says:
>>
>> "A translation unit may include library headers in any order (_lex_).
>> Each may be included more than once, with no effect different from
>> being included exactly once, except that the effect of including
>> either <cassert> or <assert.h> depends each time on the lexically cur-
>> rent definition of NDEBUG.18)"
>>
>> That seems to indicate that something is wrong with either the Standard,
>> or with the implementation.
>
> Why? This requirement is probably met by most implementations. It just
> states that

But the implementation I am discussing seems to be encountering problems
with this, so something must be wrong somewhere. I could be that I am not
fully understanding what they mean by circular dependencies.
 

>> I believe this reveals what I was saying about the failure of the
>> Standard Library to conform to the guidelines Stroustrup provides in
>> TC++PL(SE). There should be a user interface that hides such
>> implementation details. I have to ask what would go in my code to
>> correspond to these 'implementation_defined' types.
>
> The typedefs in the standard make these types available to your code by
> giving them names. These names are *the* means of using those
> implementation_defined types in your code. What these types really are is
> of no interest to the coder. (Of course, a compiler would have to know,
> but that is the difference of header files and fake headers again. Again,
> I think the standard provided fake headers, not header files.)

You are correct. I guess I have not fully adjusted to the notion of using
typedefs. I seems too much like forgery to me.
 
>
>>> [fake headers] are entirely for my own inspection. See, my C++
>>> coding style is still not very mature, and I actually prefer to not
>>> declare but to define right away (sort of the Oberon style). Now, this
>>> makes the interface hard to comprehend as code gets in the way.
>>
>> Stroustrup presents (at least)two rather distinct notions of something
>> called an interface. One is that which I have described involving the use
>> of header files. The other is the use of abstract base classes as
>> interfaces.
>
> I appologize for using the word interface. I will try hard not do that
> again. I understand that it has become a loaden term in this discussion.

No. That wasn't my intent. I was merely observing that it is a bit
difficult to think about what is really meant by the term. I just came to
realize there seems to be a truly stunning irony in the extensive use of
non-implementing APIs backed by implementations in Java.

This is Stroustrup's design:
http://xml.apache.org/xerces2-j/javadocs/xerces2/index.html

Too bad C++ programmers don't write code like that!

>> Oh, no. I'm not the expert. But my instincts tell me it's best to have
>> the interface representing the Standard Libraries created in conjunction
>> with the implementation, and indeed, they should be the source of the
>> declarations used by the compiler.
>
> This seems to be the heart of the matter. As I pointed out already, the
> compiler will need to know a lot more than I want to read in the standard.
> I do not want the standard to tell me about private members of the
> container classes.

You really should try to get a copy of Stroustrup's book. It explains how
both of these can be the case. That is, I get a foo.h user's header file
and the implementation has a foo_impl.h header file.

> Moreover, if you "are not the expert", may I assume that you have some
> experts on IDE design within reach? After all you seem to be highly
> involved in this proect and there must be some people who would actually
> try to code it. I am curious as to what they think on this matter.

The one person who would know best has been too busy to participate much. I
did notice he was back on the mailing list recently. Perhaps I should ask
again what he thinks. Much of the code has been written, and works with
many libraries.

But I have to say, the more I look at this situation, the more I realize
there is probably merit in the idea beyond it's applicability to IDEs.

> To be
> frank, it might be a little premature to ventilate changes to the standard
> before actual engineering problems in designing an IDE prove those changes
> useful. Your case will become a lot stronger once you can replace "my
> instincts" with some concrete experiences illustrating which limitations
> on IDE design are caused by shortcomings of the language.

Perhaps. OTOH, I do have a solid example from another programming language
that, as I've pointed out, seems in some ways to conform to Stroustrup's
guidelines than the C++ Standard does.
>
 
> With respect to changing a language, a good deal of conservatism seems to
> be a very reasonable attitude. Certainly, I would approve of changes only
> if they do not require serious rewriting of large portions of my code.
> Moreover, there are certain underlying design goals that sort of govern
> C++. As far as I understand, one of them is the cherished "You do not pay
> for stuff you do not use". People are choosing C++ for certain projects,
> and very likely they have reasons. Any change of C++ should not invalidate
> their reasons.

Well, I know that one of my goals has a fairly well placed advocate. I want
to remove the "#" from C++.

-- 
STH 
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org  SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org


Relevant Pages

  • Re: Header Files and Interfaces Yet Again
    ... compiler is not allowed to read them. ... illustrate the difference of header file and fake header. ... fake headers can not serve as sufficient information to the ... > something but it appears to me the Standard Library is not designed ...
    (comp.lang.cpp)
  • Re: Header Files and Interfaces Yet Again
    ... >> The point that I hope to get across is that header files need to provide ... a compiler has to know about them at compile time. ... But he actually uses what you call a fake header. ... differences between Java and C++: In Java all obects appear to be handles. ...
    (comp.lang.cpp)
  • Re: C header files--Urgent
    ... an "impossible assignment" for you. ... compiler from unix to windows and compiler is written partially in c ... If they are standard header files then ...
    (comp.lang.c)
  • Re: A C++ Whishlist
    ... A struct or class is only as 'complex' ... The standard library's consistent interface, ... > facilitate the automatic synchronization of header files. ...
    (comp.lang.cpp)
  • RfD: :NAME
    ... I posted this RfD to the Forth-200x group (originally called HEADER) ... surface of the compiler, is standard. ... There is no good way to construct colon words from within other colon ...
    (comp.lang.forth)