A summary of the #include liability

  • Thread starter Steven T. Hatton
  • Start date
S

Steven T. Hatton

I wrote this as part of a request for comments on a mailing list. I
realized it summarizes much of what I've been saying about the use of
#includes in C++. I'm not asking for the same kind of feedback on this
newsgroup as I requested on the mailing list. What I want to ask here is
whether what I am describing as a possible alternative is actually 'module'
support - as one WAG suggested. I don't believe it is. I actually believe
it is a far more modest change in how C++ code is processed.

I have convinced myself that the #include is perhaps C++'s greatest
liability. Much of this comes from the difficulty I had in learning to
work with 'header files' when first learning C++. But my dislike for
#inclusion has survived my newbie phase. I still believe it is kludge
waiting for a solution. Here are some of the reasons I believe they are
bad:

* #includes obscure the concept of translation because they can be nested;

* this makes the concept of 'file scope' unclear in many contexts;

* a single #include can drastically change the content of a translation unit
making it far more difficult to parse translation units for purposes of
code completion or validity checking

* #including is monolithic and introduces significant amounts of superfluous
content into the translation unit forcing the compiler or IDE to parse and
otherwise consider far more content than is relevant to the user code being
supported

* #including is redundant in that it is a means of introducing content into
a translation unit, and this content is already uniquely specified by the
fully qualified identifier of the type being imported. This means the
programmer and/or IDE must manipulate more information than is logically
required.



Both Java and C# have placed the burden on the implementation to resolve the
mapping between fully qualified identifiers and external entities based on
an /import/ statement, or the occurrance of the fully qualified identifier
in the body of the code. I believe this could be accomplished for C++ as
well. I also believe it would greatly improve the usability of the
language, and also improve the performance of compilers and tools such as
IDE that provide code completion and validation.

Is this module support I'm asking for?
 
I

Ioannis Vranos

Steven said:
Both Java and C# have placed the burden on the implementation to resolve the
mapping between fully qualified identifiers and external entities based on
an /import/ statement, or the occurrance of the fully qualified identifier
in the body of the code. I believe this could be accomplished for C++ as
well. I also believe it would greatly improve the usability of the
language, and also improve the performance of compilers and tools such as
IDE that provide code completion and validation.

Is this module support I'm asking for?



You are comparing a language vs frameworks. In C++ under .NET (for .NET
facilities) you do:


#using <mscorlib.dll>


using namespace System;
using namespace System::Forms;

etc.
 
S

Steven T. Hatton

Ioannis said:
You are comparing a language vs frameworks.

Yes and no. Yes, there would need to be a framework provided by the
implementation to support the specified language feature. No, I am not
proposing the C++0x Standard should specify how this framework shall be
provided. I do believe it is reasonable for the Standard to describe a
'works like this' implementation with some basis in reality.
In C++ under .NET (for .NET
facilities) you do:


#using <mscorlib.dll>


using namespace System;
using namespace System::Forms;

etc.

I believe what you are saying is, not only is it doable, it's done - in a
limited area. As I understand things, .NET won't give me the Standard
Library. Is this correct?

I would (almost) never import an entire namespace with "using namespace
System;" if I could import a single identifier such as "using
System::FooClass;". I don't "import java.net.*" in Java, even though that
is a common practice. Having explicit mention of all the identifiers used
in a file available in the heading is a powerful communication tool. But
that's one step beyond what I believe C++ should go first. I'd rather not
elaborate on ideal usage of a feature which the language does not
explicitly support.


I believe a mechanism that would work for existing C++ code bases to provide
the most elementary form of the support I'm suggesting would be to grind up
all the headers in my #include path and make something like a tags database
that would map resources to header file names. I could then have something
like "#prgama no_headers" in all my files. That would invoke some kind of
program to do the #including for me.

I'll grant you this doesn't solve many of the problems I really want solved.
I do, however, believe the exercise of producing such a tool would prove
invaluably instructive regarding how to take the next steps toward the
ideal solution.
 
I

Ioannis Vranos

Steven said:
I believe what you are saying is, not only is it doable, it's done - in a
limited area. As I understand things, .NET won't give me the Standard
Library. Is this correct?

I would (almost) never import an entire namespace with "using namespace
System;" if I could import a single identifier such as "using
System::FooClass;". I don't "import java.net.*" in Java, even though that
is a common practice. Having explicit mention of all the identifiers used
in a file available in the heading is a powerful communication tool. But
that's one step beyond what I believe C++ should go first. I'd rather not
elaborate on ideal usage of a feature which the language does not
explicitly support.


I believe a mechanism that would work for existing C++ code bases to provide
the most elementary form of the support I'm suggesting would be to grind up
all the headers in my #include path and make something like a tags database
that would map resources to header file names. I could then have something
like "#prgama no_headers" in all my files. That would invoke some kind of
program to do the #including for me.

I'll grant you this doesn't solve many of the problems I really want solved.
I do, however, believe the exercise of producing such a tool would prove
invaluably instructive regarding how to take the next steps toward the
ideal solution.



No you are missing important things! There is an upcoming C++/CLI standard.


Check a page I have been preparing as an introduction to it:

http://www23.brinkster.com/noicys/cppcli.htm




C++/CLI will make C++ the best language of CLI (and .NET):

http://microsoft.sitestream.com/TechEd/DEV/DEV333_files/Botto_files/DEV333_Sutte.ppt

http://www.accu.org/conference/pres...Relevant_on_Modern_Environments_(keynote).pdf




Also in my site I have some more info on C++/CLI (not an advertisement,
in fact I created those pages because I come across this type of
questions quite often in here).
 
S

Steven T. Hatton

Ioannis said:
No you are missing important things! There is an upcoming C++/CLI
standard.


Check a page I have been preparing as an introduction to it:

http://www23.brinkster.com/noicys/cppcli.htm

But CLI is an abstraction layer, a VM. You state on your site:

"Of course in a CLI environment you can work in mixed mode by using both ISO
C++ and C++/CLI (mixed mode does not produce pure IL code)."

That suggests I will still need to #include <vector> in order to use
std::vector<foo>. CLI is interesting, but I don't see how it directly
addresses the issues I raised regarding #include and header files.
 
J

Jack Klein

You are comparing a language vs frameworks. In C++ under .NET (for .NET
facilities) you do:


#using <mscorlib.dll>

This is not C++, no matter what you or Microsoft think.

Stop posting this off-topic twaddle here.
 
I

Ioannis Vranos

Steven said:
But CLI is an abstraction layer, a VM. You state on your site:

"Of course in a CLI environment you can work in mixed mode by using both ISO
C++ and C++/CLI (mixed mode does not produce pure IL code)."

That suggests I will still need to #include <vector> in order to use
std::vector<foo>.

Yes.



CLI is interesting, but I don't see how it directly
addresses the issues I raised regarding #include and header files.


Perhaps I did not understand what you said.May you provide a specific
example?
 
I

Ioannis Vranos

Jack said:
This is not C++, no matter what you or Microsoft think.

Stop posting this off-topic twaddle here.



Yes you are right, that dll is not even C++/CLI, but a system library.


However we are talking about inclusion mechanisms here and not a
specific library.
 
S

Steven T. Hatton

Ioannis said:
Perhaps I did not understand what you said.May you provide a specific
example?

If you merely intended to show that the .NET and CLI are doing what I want
within the limits of the environment, then, yes, it looks like that is the
case. This is encouraging in so much as it shows it can be done. Why it
has not already been done for C++ in general is beyond my ability to
comprehend.
 
I

Ioannis Vranos

Steven said:
If you merely intended to show that the .NET and CLI are doing what I want
within the limits of the environment, then, yes, it looks like that is the
case. This is encouraging in so much as it shows it can be done. Why it
has not already been done for C++ in general is beyond my ability to
comprehend.


In C++/CLI, (as far as I know) the #using directive includes a dll
(which is essentially a precompiled run-time library).

The runtime library itself must be either in the same folder with the
application, the most common, or to a special CLI implementation global
scope place.



The #include mechanism is for compile time inclusion. The one does not
replace the other.

Something similar applies with the #include mechanism and <> vs "" for
the header file.


Where exactly is the #using mechanism better than #include?
 
S

Steven T. Hatton

Ioannis said:
In C++/CLI, (as far as I know) the #using directive includes a dll
(which is essentially a precompiled run-time library).

The runtime library itself must be either in the same folder with the
application, the most common, or to a special CLI implementation global
scope place.

To some extent, that is an implementation detail. Yes, the difference is
significant in the sense that one happens under far different circumstances
than the other. But, in principle I don't believe that distinction means
the same notation could not be used at compile time.
The #include mechanism is for compile time inclusion. The one does not
replace the other.

Perhaps I am making some unfounded assumptions. For one, can I assume that
if I write my own dll code and make that available at compile time, the dll
will be compiled and then used by the compiler to compile the source that
imported it? If so, then it seems the #include is not necessary in that
case.
Where exactly is the #using mechanism better than #include?

If it applied to all code, and not just CLI runtime it would solve the
problems I enumerated in my first post in this thread. An example of how
this might be accomplished is provided by the mechanism in bjam for listing
sources required to build a target. You can list a library and have bjam
determine if the library needs to be built by evaluating a rule that names
the sources required to build the library. If the library is not
available, it is compiled at that time. The same mechanism could be
adapted to work in conjunction with using declarations in C++ source.
 
J

Jack Klein

Yes you are right, that dll is not even C++/CLI, but a system library.


However we are talking about inclusion mechanisms here and not a
specific library.

No we aren't, we are talking about your advocacy for off-topic
nonsense in this group.

'#using' is not valid C++, no matter what comes after it.

And all your b*llsh*t about some 'future standard' is meaningless
here. No matter what standard might come from any source, whether it
is an ISO standard or not, it does not become part of and has no
impact on the only standards that are topical here: ISO 14882 and the
parts of ISO 9899 it includes by reference.

So "C++/CLI" is NOT C++, and it is just as off-topic here as FORTRAN,
COBOL, or Java.
 
S

Steven T. Hatton

Jack said:
No we aren't, we are talking about your advocacy for off-topic
nonsense in this group.

'#using' is not valid C++, no matter what comes after it.

And all your b*llsh*t about some 'future standard' is meaningless
here. No matter what standard might come from any source, whether it
is an ISO standard or not, it does not become part of and has no
impact on the only standards that are topical here: ISO 14882 and the
parts of ISO 9899 it includes by reference.

So "C++/CLI" is NOT C++, and it is just as off-topic here as FORTRAN,
COBOL, or Java.

But the discussion is about the possibility of modifying C++ so that it
behaves in a way quite similar to the example presented. And I am
specifically talking about modifying the ISO/IEC 14882 so that C++ does
support such a feature. The example presented /is/ pertanant to the
discussion.

I will add that one of the features Stroustrup's has stated he would like to
see available for C++ is some kind of VM or interpreter. So again, this
topic seems relevant so long as it is kept clear that the CLI specification
deviates from the current Standard C++.

I will add that I received a reply from someone today regarding my opinions
about #include being problematic for IDE developers. Since he wrote a
significant amount of the core C++ language support for a popular
multi-lingual IDE (the implementation language is C++), I believe his
opinion can be considered that of a leading expert. Basically his answer to
the question "Are #includes evil?" was "YES!"
 
A

Andre Kostur

But the discussion is about the possibility of modifying C++ so that
it behaves in a way quite similar to the example presented. And I am
specifically talking about modifying the ISO/IEC 14882 so that C++
does support such a feature. The example presented /is/ pertanant to
the discussion.

That puts it in the realm of comp.std.c++, not comp.lang.c++.
 
S

Steven T. Hatton

Andre said:
That puts it in the realm of comp.std.c++, not comp.lang.c++.

That is your opinion. comp.std.c++ is better suited to making solid
proposals. this news group is better suited to talking about the broader
issues involved, and exploring alternatives. Since "future directions" of
C++ are explicitly mentioned in the FAQ as topics for discussion in this
news group, I don't believe there is really much more that needs to be
said.
 
I

Ioannis Vranos

Jack said:
No we aren't, we are talking about your advocacy for off-topic
nonsense in this group.

'#using' is not valid C++, no matter what comes after it.

And all your b*llsh*t about some 'future standard' is meaningless
here. No matter what standard might come from any source, whether it
is an ISO standard or not, it does not become part of and has no
impact on the only standards that are topical here: ISO 14882 and the
parts of ISO 9899 it includes by reference.

So "C++/CLI" is NOT C++, and it is just as off-topic here as FORTRAN,
COBOL, or Java.



Actually C++/CLI is an upcoming *standard* of *additional guarantees*
and structures that makes possible ISO C++ programs to take advantage of
a CLI environment where one is available. CLI is also a standard.


C++/CLI cannot exist on its own, it "brings" ISO C++ to CLI. So it does
not define what templates are for example, or what built in arrays are,
but describes how these are translated to a CLI environment.

Examples of the current draft:


"Terms not defined in this Standard are to be interpreted according to
the C++ Standard, ISO/IEC 14882:2003."



"Templates

This clause is incomplete.[[#82]]

The template syntax is the same for all types, including CLI types.

Templates on CLI types can be partially specialized, fully specialized,
and non-type parameters of any type (subject to all the
constant-expression and type rules in the C++ Standard) can be used,
with the same semantics as specified by the C++ Standard. 5

Templates are fully resolved and compiled at compile time, and reside in
their own assemblies.

Within an assembly, templates are implicitly instantiated only for the
uses of that template within the assembly."



"9.1.2 Keywords 25

The following keywords are added to those in the C++ Standard (§2.11):

enum-class enum-struct for-each gcnew
interface-class interface-struct nullptr ref-class
ref-struct value-class value-struct"



"9.1.3 Literals

The grammar for literal in the C++ Standard (§2.13) has been extended as
follows:

literal:

null-literal
9.1.3.1 The null literal
null-literal:: 5
nullptr"



etc.




But in any case were talking about inclusion mechanisms here, initially
termed as "Java's and C#'s".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top