Topic: #include and Scope of Declarations


Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/05/11
Raw View
In article <3oa3dj$cjo@hustle.rahul.net> "Ronald F. Guilmette"
<rfg@rahul.net> writes:

|> First I should say that your use of the word `module' (and its use by
|> many other people) is at best cloudy.

|> What is your definition of the term ``module''?

|> I think that if you do a bit of research you will find that this seemingly
|> innocent little term is the root of much confusion, and that it has about
|> as many different definitions as there are people who use the term.

Which is no doubt the main reason why C++ doesn't have modules yet.

I think that there would have been overwhelming support in the
standards committee for `modules' (for any reasonable definition of
module).  The problem is: there was never a concrete proposal with a
definition.

|> Second, let me also say that you are basically correct that it would have
|> been (past tense) very nice to have something in C++ which would have
|> been more along the lines of Ada's WITH statements (which themselves were
|> derived from even earlier implementations of Pascal) instead of this
|> rather undisiplined and rather error-prone approach to separate compilation
|> which we all know (and hate) as ``The C Preprocessor''.

|> Several years ago, for reasons I no longer remember, I offered Bjarne
|> Stroustroup my own thoughts on what I felt were the major issues (at
|> that time) which remained to be addressed by C++.  I clearly remember
|> that among these was the need for a _good_ and _proper_ solution to
|> the overall separate compilation problem.  Bjarne assured me that he
|> was thinking about, and working on that problem.

Actually, Bjarne did come up with a proposal, although not formally.
At that time, though, it was judged (the consensus on the mail
reflector) that it was just too late.  (If memory serves me right,
this was about 6 months ago, or may be a little more.)  So naturally,
he did not go on to develop a formal (and more rigorous) proposal.

Like you, I find that using textual inclusion of declarations to
implement separate compile the biggest single problem in C++.

|> I frankly do not know if he just gave up on the problem (because it proved
|> too hard) or if he perhaps misunderstood what _I_ meant when I spoke of
|> ``the separate compilation problem''.  In any event, here we are in 1995,
|> and the only thing that C++ has to offer in the way of facilities for
|> supporting the development of large scale software development is namespaces.
|> Although useful, namespace are _not_ in any sense a substitute for a true
|> ``import'' facility.  Sadly, it does not appear that we will be offered
|> anything else in this round.  Perhaps when the C++ standard comes up for
|> revision in 5-10 years, some additional facilities for supporting separate
|> compilation will have already been fielded by some noteworthy C++ compiler
|> vendor, and we might then get a _standard_ solution in this critical area.

I suspect that this is highly likely.  Many people expressed the
feeling that Bjarnes suggestion was a good idea.  The *only*
opposition was that it was a major proposal, and we were far too close
to the deadline to be able to give it the consideration it would
require.  I believe that your suggestion that it be considered in the
next revision was pretty much the consensus.

|> P.S.  Those who know me know that I have been adamantly opposed to any
|> further additions to the language for well over a year now.  So why (you
|> might wonder) do I here bemoan the lack of a proper import facility in C++?
|> Quite simply because _this_ was something that would have been vastly more
|> useful in large-scale software development projects than essentially all
|> of the other flotsam and jetsum we have seen added over the past several
|> years.  It's just a pity that we got lots of not-terribly-critical things
|> added to the language (e.g. bool type and wchar_t type) instead of something
|> which could really have made a big difference; i.e. proper support for
|> separate compilation.

There is a difference of degree.  The `bool' type is actually pretty
cheap, and it clarifies that language some.  I have never had much
problem with such small corrections, and the effect is (hopefully)
local.  But bool is about the limit, and at the late date I first
became involved in the standarization effort (about two years ago), I
would have automatically opposed anything more complicated on the
grounds of schedule.  (I develop on a variety of processors, and I
need to find the same language, regardless of its weaknesses, on all
of them.  Not a similar language, but the same.)
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: "Ronald F. Guilmette" <rfg@rahul.net>
Date: 1995/05/04
Raw View
In article <3nnlsc$lde@tethys.otol.fi>,
Tommi H|yn{l{nmaa <tohoyn@janus.otol.fi> wrote:
>
>If you include a header file in some other file, all the
>declarations and macro definitions before the '#include' become
>visible also in the header file. Therefore, the code before the
>'#include' may affect the behaviour of the header file. Often this
>is not what you want because the header file needs just to be
>imported in the code. Besides, I suspect that this "feature" makes
>header file precompilation a lot more difficult.
>...
>As C++ uses header files to implement modules...
>[...stuff about a suggested ``import'' feature deleted...]

First I should say that your use of the word `module' (and its use by
many other people) is at best cloudy.

What is your definition of the term ``module''?

I think that if you do a bit of research you will find that this seemingly
innocent little term is the root of much confusion, and that it has about
as many different definitions as there are people who use the term.

Second, let me also say that you are basically correct that it would have
been (past tense) very nice to have something in C++ which would have
been more along the lines of Ada's WITH statements (which themselves were
derived from even earlier implementations of Pascal) instead of this
rather undisiplined and rather error-prone approach to separate compilation
which we all know (and hate) as ``The C Preprocessor''.

Several years ago, for reasons I no longer remember, I offered Bjarne
Stroustroup my own thoughts on what I felt were the major issues (at
that time) which remained to be addressed by C++.  I clearly remember
that among these was the need for a _good_ and _proper_ solution to
the overall separate compilation problem.  Bjarne assured me that he
was thinking about, and working on that problem.

I frankly do not know if he just gave up on the problem (because it proved
too hard) or if he perhaps misunderstood what _I_ meant when I spoke of
``the separate compilation problem''.  In any event, here we are in 1995,
and the only thing that C++ has to offer in the way of facilities for
supporting the development of large scale software development is namespaces.
Although useful, namespace are _not_ in any sense a substitute for a true
``import'' facility.  Sadly, it does not appear that we will be offered
anything else in this round.  Perhaps when the C++ standard comes up for
revision in 5-10 years, some additional facilities for supporting separate
compilation will have already been fielded by some noteworthy C++ compiler
vendor, and we might then get a _standard_ solution in this critical area.

P.S.  Those who know me know that I have been adamantly opposed to any
further additions to the language for well over a year now.  So why (you
might wonder) do I here bemoan the lack of a proper import facility in C++?
Quite simply because _this_ was something that would have been vastly more
useful in large-scale software development projects than essentially all
of the other flotsam and jetsum we have seen added over the past several
years.  It's just a pity that we got lots of not-terribly-critical things
added to the language (e.g. bool type and wchar_t type) instead of something
which could really have made a big difference; i.e. proper support for
separate compilation.
--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- E-mail: rfg@segfault.us.com ----------- Purveyors of Compiler Test ----
---- finger: rfg@rahul.net ----------------- Suites and Bullet-Proof Shoes -





Author: holger@infsys.swb.de (Holger Schurig)
Date: 1995/04/29
Raw View
...
> * 'import' guarantees that the header file is included only
...

What you describe is something like the unit concept in Turbo-Pascal (and
maybe in UCSD-Pascal?).

These units consist of many parts. From the view of the coder you have a
part with "public" information, the "interface". Below of it is the
"implementation". This simple concept could maybe in some way extended.



Author: tohoyn@janus.otol.fi (Tommi H|yn{l{nmaa)
Date: 1995/04/27
Raw View
If you include a header file in some other file, all the
declarations and macro definitions before the '#include' become
visible also in the header file. Therefore, the code before the
'#include' may affect the behaviour of the header file. Often this
is not what you want because the header file needs just to be
imported in the code. Besides, I suspect that this "feature" makes
header file precompilation a lot more difficult.


Example 1:
  // Example1.cc
  #define DoSomething 1         // this is visible in Module1.h
  #include "Module1.h"
  int main()
  {
    A a(5);
  #ifdef DoSomething
    a.Print();
  #endif
    return 0;
  }
  // Program1.cc ends
  // Module1.h
  #ifndef MODULE1_H
  #define MODULE1_H
  class A
  {
  public:
    A(int);
    void Print();
  // '#define DoSomething 1' causes problems here and
  // the compiler gives an error message.
    void DoSomething();
  private:
    int n;
  };
  #endif
  // Module.h ends
  // Module.cc
  #include "Module.h"
  #include <iostream.h>
  A::A(int n_) : n(n_)  { }
  void A::Print()  { cout << n << endl; }
  void A::DoSomething()  { cout << "Hello World!" << endl; }
  // Module.cc ends

Example 2:
  // Example2.cc
  int a = 10;           // this is visible in Module2.h
  #include "Module2.h"
  #include <iostream.h>
  int main()
  {
    A b(5);
    b.Print();
    b.DoSomething();
    cout << a << endl;
    return 0;
  }
  // Example2.cc ends
  // Module2.h
  #ifndef MODULE2_H
  #define MODULE2_H
  #include <iostream.h>
  class A
  {
  public:
    A(int n_) : n(n_)
      {
      }
    void Print()
      {
      cout << n << endl;
      }
    void DoSomething()
      {
      // The following line is legal code if 'a' is declared before
      // this file is included.
      a = n;
      }
  private:
    int n;
  };
  #endif
  // Module2.h ends

As C++ uses header files to implement modules, it is important
that they do not depend on the context where they are included. I
suggest one way of solving this problem, which requires one new
keyword, for example 'import'. 'import' would differ from
'#include' in two ways:

* When a file F uses 'import' to import a header file H, the
contents of F are not visible in H. Furthermore, the contents of
any other header files that F uses are not visible in H. For
example, no macros defined in F can affect H.
If '#include''s were replaced with 'import''s in the previous
examples, example 1 would become legal code ('#define DoSomething'
would not affect 'Module1.h') and example 2 would become illegal
('a' would not be visible in 'Module2.h').

* 'import' guarantees that the header file is included only once.
Including a header file multiple times can be useful when it can
be controlled by some macros. For example, assert.h uses the macro
NDEBUG to decide if the run-time checks should be made. However,
this can't be done with 'import', anyway.

 Tommi H   yn   l   nmaa  (7-bit ASCII: H|yn{l{nmaa)