Topic: [C++0x] pragma once, anyone?


Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 5 Jun 2001 14:41:13 GMT
Raw View
In article <3B1B4163.D83A92F3@divalsim.it>, Nicola.Musatti@ObjectWay.it wrote:
>Usually modular languages forbid circular dependencies among modules, so
>that it is possible to order the modules that make up an application.
>The compiler can then keep track of the modules it has already compiled
>and issue an error if a module declares a dependency towards a module
>that hasn't been compiled yet.

Evidently this is not the case in Haskell: I recently translated a Haskell
program (the Hugs demo Mini-Prolog) into C++ in which two modules depended
on each other. Or at least, this was my impression. I have not checked the
Haskell standard on this point, but I recall it was mentioned that
recursively dependent modules should be a part of that language.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: jk@steel.orel.ru (Eugene Karpachov)
Date: Tue, 5 Jun 2001 15:31:14 GMT
Raw View
Mon,  4 Jun 2001 18:08:49 GMT Niklas Matthies =CE=C1=D0=C9=D3=C1=CC:
>On Mon,  4 Jun 2001 17:27:41 GMT, Eugene Karpachov <jk@steel.orel.ru> wr=
ote:
>> Sat,  2 Jun 2001 23:28:44 GMT Greg Brewer =CE=C1=D0=C9=D3=C1=CC:
>> >> #include "foo.h" // unchanged meaning
>> >> import "foo.h"   // read the file if not already imported
>> >
>> >Why not
>> > #import "foo.h"
>>=20
>> Why sharp? Without sharp it is obviously *language* construct, not
>> preprocessor.
>
>Because textual inclusion of files is a preprocessing activity.

Why *textual*, why inclusion of *files*? Not necessarily textual - it cou=
ld be
in precompiled form, not necessarily files - it could be "magically" know=
n to
the compiler itself as far as it is standard header. Moreover, the whole
question is about moving that activity from preprocessor to core language.

>Or how would you want
>
>   // BOF
>
>   #define NDEBUG
>   import <cassert>
>
>   int main() { assert(0); }
>
>   // EOF
>
>to behave?

I want it to behave as described by the standard, and nothing more :)

--=20
jk

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 5 Jun 2001 23:08:30 GMT
Raw View
In article <slrn9hnji6.96l.news/comp.std.c++@ns.nmhq.net>,
news/comp.std.c++@nmhq.net (Niklas Matthies) wrote:
>... how would you want
...
>   #define NDEBUG
>   import <cassert>
>
>   int main() { assert(0); }
...
>to behave?

Working along the overloading of the "using" directive, I arrive at an
additional extension:

  int main {
    using namespace std {
      #define NDEBUG
      <cassert>
    }, <iostream>;

    cout << "Hello World!" << endl;
    assert(0);
  }

Here, instead of merely indicating the name of the file to be included,
one is allowed to write in some code in needed cases.

In this would work so that the macro NDEBUG is first defined before the
file <cassert> is included. It is then possible t play around with
different types of behavior: One is that the macro NDEBUG is not valid
outside the { ... } appears within, another that it is only valid within
the scope that the "using" directive appears within.

If the former variation is chosen, then macros defined within files will
no longer be available from within C++ when included using this "using"
extension. So either one will have to rewrite old files or use the
traditional "#include" in the meantime. But the spin-off would be the
absence of local macro names in the C++ code, one would this way be able
to successive eliminate the preprocessor, as one more and more uses the
"using" directive, and new features is added to the C++ language
substituting preprocessor constructs.

Perhaps the second variation is simpler though.

But perhaps this idea is silly: The point with writing only
  using namespace std <cassert>, <iostream>;
is to tell the compiler that exactly those files should be included with
no modifications so that it does not have to worry about looking for them
again if the already have been opened and parsed.

Therefore one should perhaps look for alternative ways to achieve the
effects of a
  #define NDEBUG
  #include <cassert>
and then add that feature to the C++ language proper.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Tue, 5 Jun 2001 23:11:35 GMT
Raw View
On Tue,  5 Jun 2001 14:39:48 GMT, Eugene Karpachov <jk@steel.orel.ru> wro=
te:
> Mon,  4 Jun 2001 22:20:59 GMT Greg Brewer =CE=C1=D0=C9=D3=C1=CC:
> >> What is somewhat debatable, though, is whether
> >>
> >>    #include "foo.h"
> >>    #import  "foo.h"
> >>
> >> should insert "foo.h" once or twice.
> >
> >I vote once.  The reason for this is that foo.h may be indirectly incl=
uded.
>=20
> I'd vote to consider such a program as ill-formed, because #include is
> preprocessor directive which disappears before core compiler going to s=
tart.
> It's effect is exactly as textual inclusion, which cannot be detected i=
n
> general.

In the above example, #import was intended to be a preprocessor
directive just like #include. If the preprocessor can remember
which files it has already included via #import (which obviously is
necessary for the purpose of #import), it can also remember which files
it has already #included.

Those who think that an 'import' facility should be a core language
"directive" should start with defining what its effect should be,
especially with regard to preprocessor directives contained in the
referenced files.

-- Niklas Matthies

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Mon, 4 Jun 2001 17:45:28 GMT
Raw View

Steve Clamage wrote:
>
> On Tue, 29 May 2001, Nicola Musatti wrote:
[...]
> The C++ standard does not say anything about pragmas, except that
> "pragma" is a preprocessor directive, and that using an unknown
> pragma is not an error.
>
> By definition, pragmas specify implementation-specific behavior.
>
> For those reasons, #pragma once should not be a standard way to
> specify that a header should be included only once.

A different syntax may be devised to the same effect, so as not to
confuse the meaning of #pragma's; the only advantage of #pragma once is
that it is known to many developers.

> There are also other arguments against a non-standard #pragma once.
> A pragma should not change the semantics of a program, because of
> the unportability of pragmas.  If correctness of your program
> depends on a pragma, you open yourself to subtle problems when
> you change compilers -- maybe even to a new version of the same
> compiler.

Other precompiler directives allow changing the semantics of programs
even from the compiler's command line, so I take it that in the above
sentence you are still objecting only to the choice of #pragma to define
a standard behaviour.

[...]
> Now let's consider the problems we actually want to solve:
>
> 1. A corectness issue: We want a way to make a user-defined header
> file idempotent, meaning that including it more than once has the
> same effect as including it only once. We regard the usual
> include-guard solution as ugly and error-prone.
>
> 2. A performance issue: We assume that scanning a file more than
> once is expensive, and eliminating the scan will improve compile
> time.
>
> Regarding #2, we made some measurements with our compiler, and
> found that the extra scanning, even for fairly large files over
> a network, had negligible cost. I am willing to believe that
> for some implementations the cost is noticeable.  But we should
> consider carefully whether a change in the language standard is
> the right way to address effiency problems in compilers.

The following web page shows that include guard optimization can indeed
provide noticeable improvements in compilation time:
http://www.hottub.demon.co.uk/software/include/

[...]
> Another problem with #pragma once: The header file itself decrees
> that it should be included only once. Suppose a client of the file
> wants to include it more than once because the client redefines
> some macros in between. It should be up to the client, not the
> header itself, whether single inclusion is desired.

I tend to believe that the developer knows best how his/her own code is
meant to be used. Allowing for multiple inclusion should be a conscious
choice.

> In addition, whether #pragma once is appropriate or necessary
> can vary with changes to the file. The pragma involves a subtle
> and hidden dependency.

This is true also of include guards. I wouldn't much appreciate a piece
of documentation stating that header x.h is really meant to be included
several times so please undefine its guard after inclusion...

[...]
> So now we are back at #1, a replacement for include guards.
>
> Suggestions have been made previously for a language keyword
> such as "import" to replace the preprocessor directive #include.
> The "import" keyword (however it winds up being spelled) means
> to read the file only once. Thus, at the point of inclusion,
> not in the header itself, you can determine whether the file
> really is read.
>
>         #include "foo.h" // unchanged meaning
>         import "foo.h"   // read the file if not already imported
>
> I think further discussion should be along these lines, and let
> #pragma once die unlamented.

I din't dislike this proposal, but it can lead to tricky situations:
suppose I have:

// a.h
import "c.h"
import "b.h"

// b.h
#undef C_H_INCLUDE_GUARD
#include "c.h"

Who wins? How many times should c.h be included?

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Mon, 4 Jun 2001 17:45:19 GMT
Raw View

Hans Aberg wrote:
[...]
> >In a module based language a statement like "using iostream" would be
> >sufficient to make available all names defined in the iostream module,
> >which would be precompiled, so that any textual inclusion could be
> >avoided.
>
> I am not sure how you expect that one should somehow avoid to specify the
> file names of the modules.

Usually modular languages forbid circular dependencies among modules, so
that it is possible to order the modules that make up an application.
The compiler can then keep track of the modules it has already compiled
and issue an error if a module declares a dependency towards a module
that hasn't been compiled yet.
[...]
> If you want to add precompiled headers to the standard, and not only as a
> compiler optimization, then that precompiling process must somehow know
> where to find the modules.

I do not want to make precompiled headers standard: modules are much
more than that.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Mon, 4 Jun 2001 18:08:49 GMT
Raw View
On Mon,  4 Jun 2001 17:27:41 GMT, Eugene Karpachov <jk@steel.orel.ru> wro=
te:
> Sat,  2 Jun 2001 23:28:44 GMT Greg Brewer =CE=C1=D0=C9=D3=C1=CC:
> >> #include "foo.h" // unchanged meaning
> >> import "foo.h"   // read the file if not already imported
> >
> >Why not
> > #import "foo.h"
>=20
> Why sharp? Without sharp it is obviously *language* construct, not
> preprocessor.

Because textual inclusion of files is a preprocessing activity.
Or how would you want

   // BOF

   #define NDEBUG
   import <cassert>

   int main() { assert(0); }

   // EOF

to behave?

-- Niklas Matthies

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Mon, 4 Jun 2001 18:28:52 GMT
Raw View
On Mon,  4 Jun 2001 17:45:28 GMT, Nicola Musatti <objectway@divalsim.it> wrote:
> Steve Clamage wrote:
> > On Tue, 29 May 2001, Nicola Musatti wrote:
> [...]
> > The C++ standard does not say anything about pragmas, except that
> > "pragma" is a preprocessor directive, and that using an unknown
> > pragma is not an error.
> >
> > By definition, pragmas specify implementation-specific behavior.
> >
> > For those reasons, #pragma once should not be a standard way to
> > specify that a header should be included only once.
>
> A different syntax may be devised to the same effect, so as not to
> confuse the meaning of #pragma's; the only advantage of #pragma once is
> that it is known to many developers.

Also, standard #pragmas have been introduced by C99 (in the form of
#pragma STDC ...).

> [...]
> > So now we are back at #1, a replacement for include guards.
> >
> > Suggestions have been made previously for a language keyword
> > such as "import" to replace the preprocessor directive #include.
> > The "import" keyword (however it winds up being spelled) means
> > to read the file only once. Thus, at the point of inclusion,
> > not in the header itself, you can determine whether the file
> > really is read.
> >
> >         #include "foo.h" // unchanged meaning
> >         import "foo.h"   // read the file if not already imported
> >
> > I think further discussion should be along these lines, and let
> > #pragma once die unlamented.
>
> I din't dislike this proposal, but it can lead to tricky situations:
> suppose I have:
>
> // a.h
> import "c.h"
> import "b.h"
>
> // b.h
> #undef C_H_INCLUDE_GUARD
> #include "c.h"
>
> Who wins? How many times should c.h be included?

I think it's pretty clear that #include should continue to always
include the specified file. Nothing tricky about it.
What is somewhat debatable, though, is whether

   #include "foo.h"
   #import  "foo.h"

should insert "foo.h" once or twice.

-- Niklas Matthies

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Radoslav Getov" <nospam@mai.com>
Date: Mon, 4 Jun 2001 20:03:47 GMT
Raw View
"Steve Clamage" <clamage@eng.sun.com> wrote in message
news:Pine.SOL.3.96.1010601093656.18895A-100000@taumet...
: On Tue, 29 May 2001, Nicola Musatti wrote:
:
[snip]
: Regarding #2, we made some measurements with our compiler, and
: found that the extra scanning, even for fairly large files over
: a network, had negligible cost. I am willing to believe that
: for some implementations the cost is noticeable.  But we should
: consider carefully whether a change in the language standard is
: the right way to address effiency problems in compilers.

I also performed such a measurement, and found out that the price for just
opening an include file (MSVC, NT40) was considerable.

The test consisted of including one and the same very small header file
10000 times, using
  a) conditional #include guards,
  b) #pragma once,
  c) nothing.

It took under 0.1 seconds to compile (a) and (b) (b being slightly faster,
but the difference being within the measurement accuracy), and 10 seconds
for (c).

Radoslav Getov



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Greg Brewer" <nospam.greg@brewer.net>
Date: Mon, 4 Jun 2001 22:20:59 GMT
Raw View
"Niklas Matthies" <news/comp.std.c++@nmhq.net> wrote in message
news:slrn9hnk12.96l.news/comp.std.c++@ns.nmhq.net...
> What is somewhat debatable, though, is whether
>
>    #include "foo.h"
>    #import  "foo.h"
>
> should insert "foo.h" once or twice.

I vote once.  The reason for this is that foo.h may be indirectly included.
#import "bar.h"
#import "foo.h"

Where bar.h has
#include "foo.h"

In this case, I only want foo.h once in this module.  But another module
than only includes foo.h but not bar.h would read the file only once.

Greg



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Greg Brewer" <nospam.greg@brewer.net>
Date: Mon, 4 Jun 2001 22:21:08 GMT
Raw View
"Radoslav Getov" <nospam@mai.com> wrote in message
news:thn9an98vmai0e@corp.supernews.com...
> I also performed such a measurement, and found out that the price for just
> opening an include file (MSVC, NT40) was considerable.
>
> The test consisted of including one and the same very small header file
> 10000 times, using
>   a) conditional #include guards,
>   b) #pragma once,
>   c) nothing.
>
> It took under 0.1 seconds to compile (a) and (b) (b being slightly faster,
> but the difference being within the measurement accuracy), and 10 seconds
> for (c).

Even with fewer includes, speed can be affected by the media.  If the
include file is on a slow CDROM or on an intranet then physically reading
the file only once can be of great benefit.  In this case, there would be a
very noticable difference between a and b.

Greg


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: jk@steel.orel.ru (Eugene Karpachov)
Date: Tue, 5 Jun 2001 14:39:48 GMT
Raw View
Mon,  4 Jun 2001 22:20:59 GMT Greg Brewer =CE=C1=D0=C9=D3=C1=CC:
>> What is somewhat debatable, though, is whether
>>
>>    #include "foo.h"
>>    #import  "foo.h"
>>
>> should insert "foo.h" once or twice.
>
>I vote once.  The reason for this is that foo.h may be indirectly includ=
ed.

I'd vote to consider such a program as ill-formed, because #include is
preprocessor directive which disappears before core compiler going to sta=
rt.
It's effect is exactly as textual inclusion, which cannot be detected in
general.

--=20
jk

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 6 Jun 2001 20:16:58 GMT
Raw View
In article <slrn9hq0oi.irm.news/comp.std.c++@ns.nmhq.net>,
news/comp.std.c++@nmhq.net (Niklas Matthies) wrote:
>Those who think that an 'import' facility should be a core language
>"directive" should start with defining what its effect should be,
>especially with regard to preprocessor directives contained in the
>referenced files.

This is not so difficult: There are two possibilities, to run or not run
the file through the preprocessor before it is read by the compiler.

If the file may optionally allow some macros be prepended to the file
before it is read.

As the preprocessor is not a part of the C++ language proper, one would
get the funny effect that macros are no longer valid within the C++
translation unit, unless one radically changes  the C++ language proper
and makes it preprocessor aware.

So for example, (using "using" instead of "import"):
  using <climits>, <iostream>;

  void main() {
    std::cout << "CHAR_BIT = " << CHAR_BIT << std::endl;
  }
will not work, because CHAR_BIT is a preprocessor macro which only exists
within the preprocessor, and not the C++ language proper.

One the other hand, this kind effect is what one wants, because by using
the "using" (or "import") directive, one can ensure that one uses C++
language proper constructs and not macros.

So in the example above, one would have to write
  using <limits>, <iostream>;

  void main() {
    std::cout << "numeric_limits<unsigned char>::digits= " <<
      numeric_limits<unsigned char>::digits << std::endl;
  }
or something instead.

So I think that "using" (or "import") should not demand that the C++
language proper becomes preprocessor aware. And while awaiting the
introduction of proper C++ constructs replacing current preprocessor
usages, one will have to use "#include" if not "using" (or "import") is
working for you. Or one can write an additional file which translates
macros into C++ constructs, and then import that one; this will make the
C++ code cleaner.

In fact, one will probably get a lot of complaints by people saying "I
cannot do this or that when importing this or that module", but then one
will get a lot of ideas of how to extend the C++ language, while on the
same time diminishing the use of the preprocessor.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Greg Brewer" <nospam.greg@brewer.net>
Date: Sat, 2 Jun 2001 23:28:44 GMT
Raw View
"Steve Clamage" <clamage@eng.sun.com> wrote in message
news:Pine.SOL.3.96.1010601093656.18895A-100000@taumet...
> #include "foo.h" // unchanged meaning
> import "foo.h"   // read the file if not already imported

Why not
 #import "foo.h"

Greg Brewer


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sun, 3 Jun 2001 23:02:23 GMT
Raw View
In article <Pine.SOL.3.96.1010601093656.18895A-100000@taumet>, Steve
Clamage <clamage@eng.sun.com> wrote:
>Suggestions have been made previously for a language keyword
>such as "import" to replace the preprocessor directive #include.
>The "import" keyword (however it winds up being spelled) means
>to read the file only once. Thus, at the point of inclusion,
>not in the header itself, you can determine whether the file
>really is read.
>
>        #include "foo.h" // unchanged meaning
>        import "foo.h"   // read the file if not already imported
>
>I think further discussion should be along these lines, and let
>#pragma once die unlamented.

Actually, I like the suggestion of overloading the already present word "using":

One can then also allow to enter the filename on the fly in a local
context. For example, a version of the "Hello World" program might be:
  int main() {
    using namespace std <iostream>, <string>;
    string hello_world = "Hello World!";
    cout << hello_world << endl;
  }

-- Thus one appends a sequence of <...> or "..." filenames in order to
indicate that the names declared in those files might be used in the local
context.

It means if the example above would be followed by another code like
  void f() {
    using namespace std;
    cout << "Hello again!" << endl;
  }
it would be illegal to the already local nature of the "using" directive,
as one has not told where to find std::cout and std::endl.

The program above could still be written
  using <iostream>, <string>;

  int main() {
    using namespace std;
    string hello_world = "Hello World!";
    cout << hello_world << endl;
  }

Now the definition of f following that would be OK.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: jk@steel.orel.ru (Eugene Karpachov)
Date: Mon, 4 Jun 2001 17:27:41 GMT
Raw View
Sat,  2 Jun 2001 23:28:44 GMT Greg Brewer =CE=C1=D0=C9=D3=C1=CC:
>> #include "foo.h" // unchanged meaning
>> import "foo.h"   // read the file if not already imported
>
>Why not
> #import "foo.h"

Why sharp? Without sharp it is obviously *language* construct, not
preprocessor.

--=20
jk

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Marco Dalla Gasperina" <marcodg@home.com>
Date: Wed, 30 May 2001 21:17:18 GMT
Raw View
"Johan Ericsson" <livedog65@hotmail.com> wrote in message
news:991243031.894401@cswreg.cos.agilent.com...
[Nicola Musatti wrote]
> > I'm convinced that this is not what Marco had in mind. pimpl is actually
> > a hack where you needlessly incur the overhead of dynamic memory
> > management in order to hide implementation details.

Nicola is correct.  I wasn't referring to 'real' uses of pimpl where
it makes a difference.  My favorite is giving polymorphic objects
value semantics.

> One thing seems certain... any dynamic linking approach would prohibit
> inline functions. I'm not sure, but it seems as if dynamic linking would
> also incur the extra level of indirection on function calls.

Dynamic linking can happen at load-time or run-time (at least on
Win32).  In the former case, the loader can fix-up the addresses
so no indirection is required.

In regards to abstract classes, not everything is abstract in the
sense of being an interface to a heirarchy of types.

I have a number of non-polymorphic, concrete classes.  In these
cases I either need pimpl to hide the internals or suffer through
dependency hell.  As soon as I choose pimpl, I must forget inline
functions, and go through the hassle of typing all the forwarding
stuff.  And, I need to at least think about assignment, copies,
destruction, etc.  That's something of a pain.

marco


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 31 May 2001 15:57:54 GMT
Raw View

Johan Ericsson wrote:
[...]
> I'm not very experienced in module oriented languages, so please bear with
> me if I show my ignorance.

So am I. I just pretend not to be :-)

> One thing seems certain... any dynamic linking approach would prohibit
> inline functions. I'm not sure, but it seems as if dynamic linking would
> also incur the extra level of indirection on function calls.

The problem you mention is more general: inlining and implementation
hiding are incompatible even in C++. As for linking, Marco already
explained how it works in another post.

> How does Ada or Object Pascal's approach differ from coding against an
> abstract interface class in C++ (all pure virtual functions)? Pimpl and the
> C++ interface have a lot in common, but Pimpl allows one to use value
> semantics(support copying of types) Does Ada or Object Pascal allow value
> semantics for user defined types?

I'm not exactly sure about what happens behind the scenes, but I'll
venture a guess. Usually a module is split in an interface and an
implementation part; when pprocessing the interface, the compiler
generates the information required to compile and link modules that
depend on the current one. I don't think that there's any magic in this:
if you change the layout of a type that is used by value elsewhere, this
would trigger recompilation of the dependent module.

The main advantage in terms of compilation time comes from the fact that
module dependency must be explicitly declared and is not transitive, so
that you never get the cascading inclusion effect that's typical of C++.

> Doesn't Java have a module oriented approach? What design decisions did
> Java's designers make?

I don't think so. Java packages are more similar to C++ namespaces than
to modules.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 31 May 2001 18:51:39 GMT
Raw View
In article <slrn9h8tr4.i9.jk@localhost.localdomain>, Eugene Karpachov
<jk@steel.orel.ru> writes
>So we need additional keyword instead of "#include" - something like
>"import", or "use", or "using" etc. Consider:
>
>import vector; // Always once; not preprocessor, but core language
>import functional;
>
>instead of
>
>#include <vector>
>#include <functional>
>
>It will not break existing code.

Well as 'using' is already a keyword could it be overloaded to support:

using <vector>
using "header.h"

It even, to me, has a right feel because using is about declarations and
so, in general, are headers and header files.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 31 May 2001 19:33:32 GMT
Raw View

Jack Klein wrote:
[...]
> Many compilers support some form of precompiled headers these days, a
> mechanism I surely would not want to see standardized, that can
> provide far more efficiency in actual implementation as after the
> first source file precompiles a collection of headers the rest of the
> source files don't have to process the text at all.

Note that precompiled headers are a mixed blessings: they introduce a
very high degree of interdependency among source files which causes a
great increase in the time spent by build tools in dependency checking.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 31 May 2001 19:33:22 GMT
Raw View

Hans Aberg wrote:
[...]
> >> So, in this vein, one possible way to go would be to add an "include"
> >> directive to the C++ language. This could then read every file only once,
> >> as it would only be used in new code.
> >
> >I rather favour the introduction of a proper module mechanism, as
> >described elsewhere in this thread.
>
> The thing is that with "include" part of the C++ language proper, one can
> do many things otherwise not possible:
>
> For example, one can allow "include" to be anywhere in the source code and
> let the compiler sort it out. Take say
>    int main() {
>      include <iostream>;
>      std::cout << "Hello World!" << std::endl;
>    }
> The compiler would keep track of what has been opened.
>
> The advantage is that includes can be entered closer to the context where
> they are used. -- But in C++
>
> Further, one can think of the ability to a use a special file which
> identifies the files where the names are to be found.
> Then one could drop "include <iostream>" from the code above.

In a module based language a statement like "using iostream" would be
sufficient to make available all names defined in the iostream module,
which would be precompiled, so that any textual inclusion could be
avoided.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 31 May 2001 19:34:15 GMT
Raw View

Nicola Musatti wrote:
[...]
> > But, I'd like to start to see the end of an #include based system
> > in favor of a more module based system.  It seems like once you
> > support 'export' you've made the line between compiling and linking
> > blurry enough that maybe you can do away with it.  I think that
> > perhaps the biggest benefit would be to let 'private:' be private
> > so that adding/removing/changing private members won't cause
> > recompilation of (currently) dependent files.  The fact that
> > you have to use the pimpl idiom seems like a lot of typing
> > (particularly since there is no inherent support for delegation).
>
> Yes, *please* !!
>
> I'm under the impression that the current attitude towards the linker is
> somewhat contradictory: at one extreme template support requires
> sophisticated machinery that is found in very few other languages, if
> any at all, at the other extreme we're trying to make do with technology
> from the sixties.

What I forgot to mention in my previous message is that usually module
based languages do not share the C/C++ restriction that no knowledge
about the processing of other translation units is available during
compilation.

I would like this limitation to be removed, and I believe it necessary
to do so for proper module support, but I guess that the consequences of
such a decision must be properly evaluated.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 31 May 2001 19:33:46 GMT
Raw View

Christopher Eltschka wrote:
[...]
> Compilers relying on #pragma once are likely to not do that
> optimization and therefore #pragma once _pessimizes_ the situation
> (by lowering the pressure to do the optimization).

How's that? With include guards a compiler must make the arbitrary
assumption that the programmer's intent was really to have the header
file included only once, and then check that the guarding macro is never
undefined. The assumption is almost certainly true, but it is still an
assumption. With pragma once the programmer's intent is more clearly
specified and the optimisation is slightly easier to implement.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 31 May 2001 19:33:58 GMT
Raw View

"James Kuyper Jr." wrote:
>
> Nicola Musatti wrote:
[...]
> > Personally I don't see any cause of disruption: firstly, half the C++
> > programmers in the world are already doing this as this construct is
> > available in the most popular compiler on the most popular platform.
>
> I suspect you exaggerate the number. Even if that many programmer are
> using that compiler, I doubt that they're all using that particular
> feature. But even if you're right, here's still the other half of the
> C++ world, and an enormous amount of legacy code, most of which was
> written without use of that feature.

I most certainly do. Note however that I'm not asking for immediate
elimination of include guards, nor for deprecation of this technique.
I'd just like a less clumsy alternative to be introduced.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Thu, 31 May 2001 20:31:05 GMT
Raw View
In article <3B1642CC.BBE6A11E@divalsim.it>, Nicola.Musatti@ObjectWay.it wrote:
>> Further, one can think of the ability to a use a special file which
>> identifies the files where the names are to be found.
>> Then one could drop "include <iostream>" from the code above.
>
>In a module based language a statement like "using iostream" would be
>sufficient to make available all names defined in the iostream module,
>which would be precompiled, so that any textual inclusion could be
>avoided.

I am not sure how you expect that one should somehow avoid to specify the
file names of the modules:

In the Haskell interpreter Hugs, one assumes a connection between the
module and file names (the module <name> is found in the file named one of
several suitable endings added), but optionally, one is allowed to
indicate the filename in case there is no such name connection.

If you want to add precompiled headers to the standard, and not only as a
compiler optimization, then that precompiling process must somehow know
where to find the modules.

(Haskell also differs from C/C++ in that it checks all modules
simultaneously, admitting such things as recursive dependency between
modules.)

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Pete Becker <petebecker@acm.org>
Date: Thu, 31 May 2001 20:42:07 GMT
Raw View
Nicola Musatti wrote:
>
> Christopher Eltschka wrote:
> [...]
> > Compilers relying on #pragma once are likely to not do that
> > optimization and therefore #pragma once _pessimizes_ the situation
> > (by lowering the pressure to do the optimization).
>
> How's that? With include guards a compiler must make the arbitrary
> assumption that the programmer's intent was really to have the header
> file included only once, and then check that the guarding macro is never
> undefined.
>

It's not at all arbitrary. It describes the effect of the following
code:

#ifndef GUARD_NAME
#define GUARD_NAME
// ...
#endif

In theory the compiler could look for this sort of construct anywhere,
but in practice it occurs in headers.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Fri, 1 Jun 2001 16:33:24 GMT
Raw View

Pete Becker wrote:
>
> Nicola Musatti wrote:
[...]
> > How's that? With include guards a compiler must make the arbitrary
> > assumption that the programmer's intent was really to have the header
> > file included only once, and then check that the guarding macro is never
> > undefined.
>
> It's not at all arbitrary. It describes the effect of the following
> code:
>
> #ifndef GUARD_NAME
> #define GUARD_NAME
> // ...
> #endif
>
> In theory the compiler could look for this sort of construct anywhere,
> but in practice it occurs in headers.

Ok, maybe arbitrary is not the best adjective. I still contend that
include guards are sligthly more troublesome than pragma once. In order
to perform inclusion optimisation tha compiler has to check that no code
exists around the guard and keep trace of whether the guarding macro is
undef'ed between inclusion.
The programmer has to avoid name clashes and unmatched #if's.

I personally see no similar disadvantages for #pragma once.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Greg Brewer" <nospam.greg@brewer.net>
Date: Fri, 1 Jun 2001 16:35:07 GMT
Raw View
"Nicola Musatti" <objectway@divalsim.it> wrote in message
news:3B163F5B.7DF1B55C@divalsim.it...
> I most certainly do. Note however that I'm not asking for immediate
> elimination of include guards, nor for deprecation of this technique.

I don't think it is possible to eliminate include guards without
fundamentally changing the language.  After all, the include guards are just
conditional sections of code.

However, a less combersome method would be nice.

Greg


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Steve Clamage <clamage@eng.sun.com>
Date: Sat, 2 Jun 2001 02:30:08 GMT
Raw View
On Tue, 29 May 2001, Nicola Musatti wrote:

> I have a small request for the next issue of the standard. As I
> personally consider include guards a hack, albeit a necessary one, why
> not introduce the alternative "#pragma once", already supported by some
> compilers, to tell the compiler that the currently included source file
> should not be read again while processing the current translation unit?

The C++ standard does not say anything about pragmas, except that
"pragma" is a preprocessor directive, and that using an unknown
pragma is not an error.

By definition, pragmas specify implementation-specific behavior.

For those reasons, #pragma once should not be a standard way to
specify that a header should be included only once.

There are also other arguments against a non-standard #pragma once.

A pragma should not change the semantics of a program, because of
the unportability of pragmas.  If correctness of your program
depends on a pragma, you open yourself to subtle problems when
you change compilers -- maybe even to a new version of the same
compiler.

The effect of including a file more than once is defined by the
standard. You therefore do not want to depend on a pragma to
change that effect.

Now let's consider the problems we actually want to solve:

1. A corectness issue: We want a way to make a user-defined header
file idempotent, meaning that including it more than once has the
same effect as including it only once. We regard the usual
include-guard solution as ugly and error-prone.

2. A performance issue: We assume that scanning a file more than
once is expensive, and eliminating the scan will improve compile
time.

Regarding #2, we made some measurements with our compiler, and
found that the extra scanning, even for fairly large files over
a network, had negligible cost. I am willing to believe that
for some implementations the cost is noticeable.  But we should
consider carefully whether a change in the language standard is
the right way to address effiency problems in compilers.

For example, the gnu compilers implemented #pragma once, but
later changed the implementation to recognize the include-
guard pattern. When a file is included, the compiler notes
the include guard if the entire file is guarded. Upon seeing
another include directive, the compiler checks the include
guard, and simply ignores the include directive if the guard
is satisfied. My understanding is that the gnu compilers no
longer implement #pragma once. The pragma would not be needed,
in any event.

Another problem with #pragma once: The header file itself decrees
that it should be included only once. Suppose a client of the file
wants to include it more than once because the client redefines
some macros in between. It should be up to the client, not the
header itself, whether single inclusion is desired.

In addition, whether #pragma once is appropriate or necessary
can vary with changes to the file. The pragma involves a subtle
and hidden dependency.

The compiler approach I describe above neatly solves these problems
without compromising correctness. The compiler determines during
each compilation whether the header is idempotent, and verifies
at each subsequent include whether the include guard is satisfied.
Whatever performance improvement is available comes without any
extra work from the programmer.

So now we are back at #1, a replacement for include guards.

Suggestions have been made previously for a language keyword
such as "import" to replace the preprocessor directive #include.
The "import" keyword (however it winds up being spelled) means
to read the file only once. Thus, at the point of inclusion,
not in the header itself, you can determine whether the file
really is read.

 #include "foo.h" // unchanged meaning
 import "foo.h"   // read the file if not already imported

I think further discussion should be along these lines, and let
#pragma once die unlamented.

---
Steve Clamage, stephen.clamage@sun.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Wed, 30 May 2001 10:45:41 GMT
Raw View

"C. M. Heard" wrote:
[...]
> It's not at all obvious to me that this proposal provides any benefit
> beyond making it slightly less of a nuisance to write include guards.
> I can't see it being worth the disruption.
>
> As a practical matter, traditional include guards would have to remain
> supported owing to the vast body of existing code (including in
> particular header files shared between C and C++).

Personally I don't see any cause of disruption: firstly, half the C++
programmers in the world are already doing this as this construct is
available in the most popular compiler on the most popular platform.
Secondly, I'm aware that include guards cannot be eliminated, and even
if deprecated, will stay around for many, many years. Still, I'd like
the choice to use a more convenient and safe approach.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Wed, 30 May 2001 10:45:20 GMT
Raw View

Marco Dalla Gasperina wrote:
[...]
> I would agree with this.  Especially since standardizing it would
> be codifyin existing practice.  I know that I've misspelled an
> include guard once or twice causing me a certain amount of grief.

Not to mention the ever present risk of clashing with other include
guards.

> But, I'd like to start to see the end of an #include based system
> in favor of a more module based system.  It seems like once you
> support 'export' you've made the line between compiling and linking
> blurry enough that maybe you can do away with it.  I think that
> perhaps the biggest benefit would be to let 'private:' be private
> so that adding/removing/changing private members won't cause
> recompilation of (currently) dependent files.  The fact that
> you have to use the pimpl idiom seems like a lot of typing
> (particularly since there is no inherent support for delegation).

Yes, *please* !!

I'm under the impression that the current attitude towards the linker is
somewhat contradictory: at one extreme template support requires
sophisticated machinery that is found in very few other languages, if
any at all, at the other extreme we're trying to make do with technology
from the sixties.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Wed, 30 May 2001 10:46:00 GMT
Raw View

Hans Aberg wrote:
[...]
> It was discussed elsewhere how to eliminate the preprocessor. This would
> mean to move the preprocessor features over to the C++ language.

I guess I missed this discussion. If the net result is just the removal
of the leading '#' sign, it's not worth the effort :-)

> So, in this vein, one possible way to go would be to add an "include"
> directive to the C++ language. This could then read every file only once,
> as it would only be used in new code.

I rather favour the introduction of a proper module mechanism, as
described elsewhere in this thread.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Wed, 30 May 2001 15:39:35 GMT
Raw View

James Dennett wrote:
[...]
> I don't like the idea of standardising #pragmas -- #pragma is
> currently a signal that non-portable things are happening.

I see your point, but I still feel that compiler directives should be
kept separate from the proper language. This is why I don't like the
export keyword (1), which has no real relationship with language
semantics.

Furthermore, it might be a good idea to predefine a given set of
optional pragmas, in order to ensure that the same functionality is
implemented in the same way in all the compilers that support it.

> I would like a proper (if simple) module system in C++.

Oh, yes.

> A first pass might just be a "#import" which acts like
> #include except for not allowing repeated inclusion.
> There are issues with working out if different names
> refer to the same file (as found in gcc, which effectively
> does this already for files which have explicit include
> guards) but I'm sure a solution can be found.

I'm not familiar with the problems you describe. I would expect each
module to implicitly introduce a namespace that cannot be reopened.

Best regards,
Nicola Musatti

(1) How can I say that, when I never even met it? :-)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: jk@steel.orel.ru (Eugene Karpachov)
Date: Wed, 30 May 2001 16:31:31 GMT
Raw View
Tue, 29 May 2001 19:45:20 GMT James Dennett wrote:
>Matvei Brodski wrote:
>> Can we have the opposite? I mean: why do we want compiler to include some
>> file few times by default? All the information necessary to conclude that
>> some file has already been included is available to a compiler, so, why not
>> making "including one time only" policy the default one, and then put
>> "#pragma twice" in those files that have to be included every time they
>> mentioned (why would we want it anyway?).
>
>This would break existing code, some of which deliberately
>includes files twice with different #defines.

So we need additional keyword instead of "#include" - something like
"import", or "use", or "using" etc. Consider:

import vector; // Always once; not preprocessor, but core language
import functional;

instead of

#include <vector>
#include <functional>

It will not break existing code.

--
jk

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Jack Klein <jackklein@spamcop.net>
Date: Wed, 30 May 2001 16:32:04 GMT
Raw View
On Tue, 29 May 2001 19:15:43 GMT, "C. M. Heard" <heard@vvnet.com>
wrote in comp.std.c++:

> > I have a small request for the next issue of the standard. As I
> > personally consider include guards a hack, albeit a necessary one, why
> > not introduce the alternative "#pragma once", already supported by some
> > compilers, to tell the compiler that the currently included source file
> > should not be read again while processing the current translation unit?
> >
> > I believe this alternative to be a clearer way to state the intended
> > behaviour and less error prone than include guards.
>
> It's not at all obvious to me that this proposal provides any benefit
> beyond making it slightly less of a nuisance to write include guards.
> I can't see it being worth the disruption.
>
> As a practical matter, traditional include guards would have to remain
> supported owing to the vast body of existing code (including in
> particular header files shared between C and C++).
>
> //cmh

Actually there could be a significant improvement.  Assuming a header
file started out with the typical:

#ifndef INCLUDE_GUARD
#define INCLUDE_GUARD
/* */
#endif // INCLUDE_GUARD

The preprocessor at least must process the entire file looking for the
matching #endif unless it retains a fair amount of information about
the contents of the header itself.

I have mixed feelings about this idea.  Not to pick on Microsoft
particularly, others might be as bad, but the last time I checked
including windows.h in a source file, with all of its nested includes,
amounted to about 600K octets of text.  If you are a believer in all
headers being stand-alone, a Windows GUI application source file might
include the headers for a large number of classes that each include
windows.h.

Many compilers support some form of precompiled headers these days, a
mechanism I surely would not want to see standardized, that can
provide far more efficiency in actual implementation as after the
first source file precompiles a collection of headers the rest of the
source files don't have to process the text at all.

BTW, I am not MS bashing.  For all I know XWindows or Macintosh, etc.,
might be just as bad as Windows.  I just use this as an example
because I am somewhat familiar with it.

--
Jack Klein
Home: http://JK-Technology.Com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Wed, 30 May 2001 16:32:17 GMT
Raw View

Johan Ericsson wrote:
[...]
> Making a type "opaque" through the use of the pimpl idiom is very useful.
> Unfortunately, it also requires an almost mechanical procedure. It would be
> helpful if the standard provided some support for implementing pimpl
> classes.
>
> It is almost certainly not desirable to redefine "private:" to mean pimpl
> for all cases. There are performance penalties for using pimpl:
>         * Accessing data through a pimpl class requires an extra level of
> indirection.
>         * Creating a pimpl class requires the use of the free store...
> classes can't be created on the stack (since the size can't be determined by
> the calling site)
>         * Inline can't be used through the pimpl class

I'm convinced that this is not what Marco had in mind. pimpl is actually
a hack where you needlessly incur the overhead of dynamic memory
management in order to hide implementation details. Languages as Ada or
Borland's Object Pascal provide a mechanism that allows you to export
from a module only the interface of classes and functions.

With the help of the compiler/linker chain this lets you modify your
implementations without recompiling dependent modules. If you use
dynamic libraries you don't even need relinking.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 30 May 2001 16:33:53 GMT
Raw View
In article <3B14BBA8.BE06287F@divalsim.it>, Nicola.Musatti@ObjectWay.it wrote:
>> It was discussed elsewhere how to eliminate the preprocessor. This would
>> mean to move the preprocessor features over to the C++ language.
>
>I guess I missed this discussion. If the net result is just the removal
>of the leading '#' sign, it's not worth the effort :-)

The preprocessor is not really a part of the C/C++ languages, but a
separate language in itself.

This attempt would a part of the effort that already has been underway
with many other C++ features (templates, etc.).

>> So, in this vein, one possible way to go would be to add an "include"
>> directive to the C++ language. This could then read every file only once,
>> as it would only be used in new code.
>
>I rather favour the introduction of a proper module mechanism, as
>described elsewhere in this thread.

The thing is that with "include" part of the C++ language proper, one can
do many things otherwise not possible:

For example, one can allow "include" to be anywhere in the source code and
let the compiler sort it out. Take say
   int main() {
     include <iostream>;
     std::cout << "Hello World!" << std::endl;
   }
The compiler would keep track of what has been opened.

The advantage is that includes can be entered closer to the context where
they are used. -- But in C++

Further, one can think of the ability to a use a special file which
identifies the files where the names are to be found.

Then one could drop "include <iostream>" from the code above.

I have used this idea in an OOPL I am writing on: In this language
compiler, which outputs C++ code, one can write (translated into C++ like
pseudo-code)
    class A <iostream> { ... };
Here the <iostream> would merely mean that that header should be read. I
then merely sort the headers alphabetically, and includes them in the C++
output.

Whatever, one has the chance of better control over it, if the feature is
entered into the C++ language proper.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Johan Ericsson" <livedog65@hotmail.com>
Date: Wed, 30 May 2001 17:23:08 GMT
Raw View
> > It is almost certainly not desirable to redefine "private:" to mean
pimpl
> > for all cases. There are performance penalties for using pimpl:
> >         * Accessing data through a pimpl class requires an extra level
of
> > indirection.
> >         * Creating a pimpl class requires the use of the free store...
> > classes can't be created on the stack (since the size can't be
determined by
> > the calling site)
> >         * Inline can't be used through the pimpl class
>
> I'm convinced that this is not what Marco had in mind. pimpl is actually
> a hack where you needlessly incur the overhead of dynamic memory
> management in order to hide implementation details. Languages as Ada or
> Borland's Object Pascal provide a mechanism that allows you to export
> from a module only the interface of classes and functions.
>
> With the help of the compiler/linker chain this lets you modify your
> implementations without recompiling dependent modules. If you use
> dynamic libraries you don't even need relinking.
>
Thank you for your explanation.

I'm not very experienced in module oriented languages, so please bear with
me if I show my ignorance.

One thing seems certain... any dynamic linking approach would prohibit
inline functions. I'm not sure, but it seems as if dynamic linking would
also incur the extra level of indirection on function calls.

How does Ada or Object Pascal's approach differ from coding against an
abstract interface class in C++ (all pure virtual functions)? Pimpl and the
C++ interface have a lot in common, but Pimpl allows one to use value
semantics(support copying of types) Does Ada or Object Pascal allow value
semantics for user defined types?

Doesn't Java have a module oriented approach? What design decisions did
Java's designers make?

Thank you,
Johan


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 30 May 2001 19:07:27 GMT
Raw View
Nicola Musatti wrote:
>
> "C. M. Heard" wrote:
...
> > As a practical matter, traditional include guards would have to remain
> > supported owing to the vast body of existing code (including in
> > particular header files shared between C and C++).
>
> Personally I don't see any cause of disruption: firstly, half the C++
> programmers in the world are already doing this as this construct is
> available in the most popular compiler on the most popular platform.

I suspect you exaggerate the number. Even if that many programmer are
using that compiler, I doubt that they're all using that particular
feature. But even if you're right, here's still the other half of the
C++ world, and an enormous amount of legacy code, most of which was
written without use of that feature.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Wed, 30 May 2001 19:29:11 GMT
Raw View
Jack Klein wrote:
>
> On Tue, 29 May 2001 19:15:43 GMT, "C. M. Heard" <heard@vvnet.com>
> wrote in comp.std.c++:
>
> > > I have a small request for the next issue of the standard. As I
> > > personally consider include guards a hack, albeit a necessary one, why
> > > not introduce the alternative "#pragma once", already supported by some
> > > compilers, to tell the compiler that the currently included source file
> > > should not be read again while processing the current translation unit?
> > >
> > > I believe this alternative to be a clearer way to state the intended
> > > behaviour and less error prone than include guards.
> >
> > It's not at all obvious to me that this proposal provides any benefit
> > beyond making it slightly less of a nuisance to write include guards.
> > I can't see it being worth the disruption.
> >
> > As a practical matter, traditional include guards would have to remain
> > supported owing to the vast body of existing code (including in
> > particular header files shared between C and C++).
> >
> > //cmh
>
> Actually there could be a significant improvement.  Assuming a header
> file started out with the typical:
>
> #ifndef INCLUDE_GUARD
> #define INCLUDE_GUARD
> /* */
> #endif // INCLUDE_GUARD
>
> The preprocessor at least must process the entire file looking for the
> matching #endif unless it retains a fair amount of information about
> the contents of the header itself.

That "fair amount" is the name of the include guard, and the fact
that nothing except whitespace and comments appeared outside of them.

Indeed, g++ has had this optimization quite a while now.

>
> I have mixed feelings about this idea.  Not to pick on Microsoft
> particularly, others might be as bad, but the last time I checked
> including windows.h in a source file, with all of its nested includes,
> amounted to about 600K octets of text.  If you are a believer in all
> headers being stand-alone, a Windows GUI application source file might
> include the headers for a large number of classes that each include
> windows.h.

And if windows.h has proper include guards, the compiler doesn't
even need to open it twice (even less read it twice) - assuming it
does the simple optimization mentioned above.

Compilers relying on #pragma once are likely to not do that
optimization and therefore #pragma once _pessimizes_ the situation
(by lowering the pressure to do the optimization).

>
> Many compilers support some form of precompiled headers these days, a
> mechanism I surely would not want to see standardized, that can
> provide far more efficiency in actual implementation as after the
> first source file precompiles a collection of headers the rest of the
> source files don't have to process the text at all.

_That_ is a different topic: Now we are speaking about _different_
translation units (which of course _each_ has to include the header
at least once). For this case, #pragma once doesn't help at all;
precompiled headers do help here.

[...]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Tue, 29 May 2001 13:19:34 GMT
Raw View
Hallo, everybody.
I have a small request for the next issue of the standard. As I
personally consider include guards a hack, albeit a necessary one, why
not introduce the alternative "#pragma once", already supported by some
compilers, to tell the compiler that the currently included source file
should not be read again while processing the current translation unit?

I believe this alternative to be a clearer way to state the intended
behaviour and less error prone than include guards.

Best regards,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Marco Dalla Gasperina" <marcodg@home.com>
Date: Tue, 29 May 2001 19:13:34 GMT
Raw View
"Nicola Musatti" <objectway@divalsim.it> wrote in message
news:3B1356FC.85B2BEAD@divalsim.it...
> Hallo, everybody.
> I have a small request for the next issue of the standard. As I
> personally consider include guards a hack, albeit a necessary one, why
> not introduce the alternative "#pragma once", already supported by some
> compilers, to tell the compiler that the currently included source file
> should not be read again while processing the current translation unit?
>
> I believe this alternative to be a clearer way to state the intended
> behaviour and less error prone than include guards.

I would agree with this.  Especially since standardizing it would
be codifyin existing practice.  I know that I've misspelled an
include guard once or twice causing me a certain amount of grief.

But, I'd like to start to see the end of an #include based system
in favor of a more module based system.  It seems like once you
support 'export' you've made the line between compiling and linking
blurry enough that maybe you can do away with it.  I think that
perhaps the biggest benefit would be to let 'private:' be private
so that adding/removing/changing private members won't cause
recompilation of (currently) dependent files.  The fact that
you have to use the pimpl idiom seems like a lot of typing
(particularly since there is no inherent support for delegation).

marco


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "C. M. Heard" <heard@vvnet.com>
Date: Tue, 29 May 2001 19:15:43 GMT
Raw View
> I have a small request for the next issue of the standard. As I
> personally consider include guards a hack, albeit a necessary one, why
> not introduce the alternative "#pragma once", already supported by some
> compilers, to tell the compiler that the currently included source file
> should not be read again while processing the current translation unit?
>
> I believe this alternative to be a clearer way to state the intended
> behaviour and less error prone than include guards.

It's not at all obvious to me that this proposal provides any benefit
beyond making it slightly less of a nuisance to write include guards.
I can't see it being worth the disruption.

As a practical matter, traditional include guards would have to remain
supported owing to the vast body of existing code (including in
particular header files shared between C and C++).

//cmh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Matvei Brodski <mbrodski@bear.com>
Date: Tue, 29 May 2001 19:28:30 GMT
Raw View

Nicola Musatti wrote:

> Hallo, everybody.
> I have a small request for the next issue of the standard. As I
> personally consider include guards a hack, albeit a necessary one, why
> not introduce the alternative "#pragma once", already supported by some
> compilers, to tell the compiler that the currently included source file
> should not be read again while processing the current translation unit?
>
> I believe this alternative to be a clearer way to state the intended
> behaviour and less error prone than include guards.

Can we have the opposite? I mean: why do we want compiler to include some
file few times by default? All the information necessary to conclude that
some file has already been included is available to a compiler, so, why not
making "including one time only" policy the default one, and then put
"#pragma twice" in those files that have to be included every time they
mentioned (why would we want it anyway?).

Matvei.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: James Dennett <jdennett@acm.org>
Date: Tue, 29 May 2001 19:45:20 GMT
Raw View
Matvei Brodski wrote:
>
> Nicola Musatti wrote:
>
> > Hallo, everybody.
> > I have a small request for the next issue of the standard. As I
> > personally consider include guards a hack, albeit a necessary one, why
> > not introduce the alternative "#pragma once", already supported by some
> > compilers, to tell the compiler that the currently included source file
> > should not be read again while processing the current translation unit?
> >
> > I believe this alternative to be a clearer way to state the intended
> > behaviour and less error prone than include guards.
>
> Can we have the opposite? I mean: why do we want compiler to include some
> file few times by default? All the information necessary to conclude that
> some file has already been included is available to a compiler, so, why not
> making "including one time only" policy the default one, and then put
> "#pragma twice" in those files that have to be included every time they
> mentioned (why would we want it anyway?).

This would break existing code, some of which deliberately
includes files twice with different #defines.

<cassert> is an example of a header file which is required
to be usable in this manner.

I don't like the idea of standardising #pragmas -- #pragma is
currently a signal that non-portable things are happening.
I would like a proper (if simple) module system in C++.
A first pass might just be a "#import" which acts like
#include except for not allowing repeated inclusion.
There are issues with working out if different names
refer to the same file (as found in gcc, which effectively
does this already for files which have explicit include
guards) but I'm sure a solution can be found.

-- James Dennett

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 29 May 2001 21:12:39 GMT
Raw View
In article <3B1356FC.85B2BEAD@divalsim.it>, Nicola.Musatti@ObjectWay.it wrote:
>I have a small request for the next issue of the standard. As I
>personally consider include guards a hack, albeit a necessary one, why
>not introduce the alternative "#pragma once", already supported by some
>compilers, to tell the compiler that the currently included source file
>should not be read again while processing the current translation unit?

It was discussed elsewhere how to eliminate the preprocessor. This would
mean to move the preprocessor features over to the C++ language.

So, in this vein, one possible way to go would be to add an "include"
directive to the C++ language. This could then read every file only once,
as it would only be used in new code.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Johan Ericsson" <livedog65@hotmail.com>
Date: Tue, 29 May 2001 23:51:01 GMT
Raw View
> blurry enough that maybe you can do away with it.  I think that
> perhaps the biggest benefit would be to let 'private:' be private
> so that adding/removing/changing private members won't cause
> recompilation of (currently) dependent files.  The fact that
> you have to use the pimpl idiom seems like a lot of typing
> (particularly since there is no inherent support for delegation).

Making a type "opaque" through the use of the pimpl idiom is very useful.
Unfortunately, it also requires an almost mechanical procedure. It would be
helpful if the standard provided some support for implementing pimpl
classes.

It is almost certainly not desirable to redefine "private:" to mean pimpl
for all cases. There are performance penalties for using pimpl:
        * Accessing data through a pimpl class requires an extra level of
indirection.
        * Creating a pimpl class requires the use of the free store...
classes can't be created on the stack (since the size can't be determined by
the calling site)
        * Inline can't be used through the pimpl class

Johan


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]