Topic: What counts as "language" ?
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sun, 18 Sep 1994 06:14:42 GMT Raw View
matt@physics16.berkeley.edu (Matt Austern) writes:
>My proposal (which really is semi-serious) is essentially that
>everything in std:: be predefined, regardless of whether any #include
>lines are present. I don't see how this would break any user code,
>since user code can't define any symbols in std:: anyway.
Ah. This proposal is different to what I thought you were suggesting -
"everything in the standard header files is predefined".
With this proposal, none of the macros defined in the standard headers
are automatically predefined.
Note that
int main() {
cin << "Hello world" << endl;
return 0;
}
would still be an error. You would have to write either
int main() {
std::cin << "Hello world" << std::endl;
return 0;
}
or
using namespace std;
int main() {
cin << "Hello world" << endl;
return 0;
}
Also note that you would still need to #include the appropriate
header files to get assert(), offsetof(), etc.
--
Fergus Henderson - fjh@munta.cs.mu.oz.au
Author: matt@physics16.berkeley.edu (Matt Austern)
Date: 14 Sep 1994 23:21:12 GMT Raw View
In article <9424700.28003@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
> >Here's a semi-serious proposal: get rid of the requirement that a
> >program using cin have the line "#include <iostream.h>", and that a
> >program using sin have the line "#include <math.h>". Unless I've
> >completely misunderstood this whole discussion, this wouldn't break
> >any valid program.
> Well, it *would* break some valid programs. The reason is that
> some parts of the namespace only become reserved for the implementation
> if the header file is included. Otherwise, the name can be used
> by the programmer.
I'm not sure that this is true. I haven't seen the latest
specification of namespace, nor have I seen a compiler that implements
them, but my understanding was that things like cin are defined in the
std:: namespace, but that if I declare a variable (regardless of
whether or not it has external linkage) without specifying its
namespace, it gets defined in the global (unnamed) namespace. Am I
mistaken?
My proposal (which really is semi-serious) is essentially that
everything in std:: be predefined, regardless of whether any #include
lines are present. I don't see how this would break any user code,
since user code can't define any symbols in std:: anyway.
--
--matt
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sat, 3 Sep 1994 14:03:20 GMT Raw View
matt@physics16.berkeley.edu (Matt Austern) writes:
>maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>
>> There is no step to take. The C++ library isnt a library
>> of functions and classes. It is an intrinsic part of the language.
You should say that the C++ standard library isn't *necessarily*
a library of functions and classes.
[...]
>In principle, maybe that's true. However, there are two crucial
>differences between the library and [the rest of] the language.
There is a distinction between the standard library and the builtin
language features, but there is also a distinction between
the standard library and ordinary libraries. There are three
categories, not just two. It doesn't make sense to lump the standard
library in with either.
[...]
>First, in order to use anything from the library I have to have the
>line "#include <XXX.h>" in every file of my program where that feature
>is used
Actually, that's not completely true. There are parts of the library that can
be used without any #include. For example, an expression like
int *p = new int;
invokes the standard library function `::operator new()'. This may in turn
throw an exception of the standard library class `alloc', which may
cause the standard library functions `terminate()' and `abort()' to be
called.
>Second, and more important: in practice, most compiler implementations
>don't treat the library as if it's part of the language. The library
>usually is separately written, and expressions like sin(x) are usually
>treated just like any other function calls.
This is certainly true of many implementations, but implementations
which treat calls to certain functions (e.g. `memcpy()') specially are
becoming more-and-more common.
>Compilers usually don't
>diagnose errors in calling library functions: that is, they usually
>just check the function signature, like they do with any other
>function call, rather than using any special knowledge about which
>arguments values are valid and which preconditions have been
>satisfied.
Yes, but again usually is not the same as always. Some compilers do
diagnose errors in calling library functions such as `printf()'.
>In some implementions, in fact, you have to give the
>compiler special switches to use parts of the library. (-lm, and so
>on.)
Yes, but in some implementations you also have to give the compiler special
switches to use parts of the language! (For example trigraphs,
exception handling, and RTTI.)
>Regardless of whether the library is theoretically an intrinsic part
>of the language, this isn't the way that it tends to be treated in
>practice.
Sure. That's because implementing the library as ordinary classes
and functions is a very easy way to do it. It doesn't mean that
that's the only way, or that it's always the best way. For many
implementations some part of the standard library will be implemented
differently.
>And, I submit, there's a lot of language in the ARM that
>encourages compiler writers and programmers to think of the standard
>C++ library as if it's just another library of functions and classes.
[...]
>if the library really is an intrinsic part of the language, it ought
>to be documented that way.
As I said before, there are three categories:
- builtin language features
- the standard library
- ordinary C++ code
The standard library should not be confused with either of the other
two categories.
But the standard should not document how it is implemented - after
It should not be documented as being
For the most part,
Whether it is implemented using special magic in the compiler or
as
>Here's a semi-serious proposal: get rid of the requirement that a
>program using cin have the line "#include <iostream.h>", and that a
>program using sin have the line "#include <math.h>". Unless I've
>completely misunderstood this whole discussion, this wouldn't break
>any valid program.
Well, it *would* break some valid programs. The reason is that
some parts of the namespace only become reserved for the implementation
if the header file is included. Otherwise, the name can be used
by the programmer. For example, the following program
static int cout = 0; // note: static, not extern
main() {
cout << 7; // this has no effect
return 0;
}
is conforming C/C++ - but would not be conforming if it #included <iostream.h>.
With your suggestion, these parts of the namespace would have to be
reserved for the implementation even if the header file wasn't
included, which would break the above program.
>It would be a tiny bit of extra work for implementors, but only a tiny bit.
In addition to the problem mentioned above, it could be very difficult
to implement without reducing compilation speed, since implementations
which implemented the standard library using ordinary header files
would have to automatically include every standard library header file.
--
Fergus Henderson - fjh@munta.cs.mu.oz.au
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Fri, 2 Sep 1994 23:53:33 GMT Raw View
In article <MATT.94Aug23131013@physics16.berkeley.edu> matt@physics.berkeley.edu writes:
>In article <CuDCxK.G42@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>> There is no step to take. The C++ library isnt a library
>> of functions and classes. It is an intrinsic part of the language.
>> It is simply described "as if" it were a library to make that
>> part of the language easy to specify and make consistent.
>
>In principle, maybe that's true. However, there are two crucial
>differences between the library and [the rest of] the language. Both
>of these differences are largely ones of how we name things, but, as I
>said above, it's the nominal distinction that should perhaps be
>removed.
>
>First, in order to use anything from the library I have to have the
>line "#include <XXX.h>" in every file of my program where that feature
>is used; I have to look up what that XXX is for each library feature
>I'm interested in. This doesn't seem very much like the library is
>part of the language; I'd certainly find it odd if I had to write
>"#include <forloops.h>" in every program where I used a for statement.
I agree. I strongly object to this archaic carry over
from C. In C there was an excuse (efficiency), in C++
#include is LESS efficient and a pain in the butt.
As I understand it in C++ there will be a
#include <all>
after which you control the library use with namespaces.
>
>Second, and more important: in practice, most compiler implementations
>don't treat the library as if it's part of the language.
My compiler treats _some_ of the functions as intrinsics.
Like memcpy.
>the C library that way.) It might be a good idea to look carefully
>for that language and to get rid of it; if the library really is an
>intrinsic part of the language, it ought to be documented that way.
>
>I was rather surprised, actually, to learn that functions and classes
>in the standard library were quite this special. I suspect that I'm
>not the only programmer who was unaware of this, and I suspect that
>many compiler vendors are unaware.
Its simple. The classes in the Standard library differ
from "ordinary" user written ones in one very important respect.
The compiler _knows_ the semantics of the classes. That means
it can do optimisations. For example the class
complex<float>
can be optimised assuming things about complex numbers that could
not be assumed for a user written class -- although if the
compiler was really super smart it might be able to deduces
some semantics from the user source code. (But C/C++ is
a very poor language for that purpose).
So complex<float> has the same status as "float".
It is exactly a built in type. It happens to also have
addressable member functions -- but these dont need to
be generated unless called, and the compiler itself
doesnt have to call any member functions -- it can just
generate code.
MOST compilers will only do a small amount of
such optimisation today. But you can be they will do more
and more as competition hots up. (That is, after vendors get
them working at all)
[get rid of #include ..]
Yep. I agree. I hate the way those stupid #includes
clutter up my code. And these days, they just aren't necessary.
(But I wont waste my time proposing it yet again. .. Oh well,
good Eiffel compilers are beginning to become available now :-)
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd,
81A Glebe Point Rd, GLEBE Mem: SA IT/9/22,SC22/WG21
NSW 2037, AUSTRALIA Phone: 61-2-566-2189
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Thu, 11 Aug 1994 11:51:19 GMT Raw View
In article <MATT.94Aug9172510@physics2.berkeley.edu> matt@physics.berkeley.edu writes:
>In article <3293dg$4f5@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:
>
>I'm wondering, then: if, regardless of whether my program contains the
>line "#include <math.h>", I'm unable to define my own function
>::sin(double), then does it serve any useful purpose to require my
>program to contain that line?
you can define your own sin(double) if you do NOT
include math.h because the standard library routine is
called
std::sin(double)
i.e. it lives in a namespace. Same for malloc. Roll your own,
the standard library malloc is called
std:malloc
and you cant redefine THAT.
>
>Or, to put it slightly differently: if the line between the language
>and the library has gotten this blurry, maybe it makes more sense to
>erase that line altogether. FORTRAN has the notion of "intrinsic
>functions", predefined functions that are part of the language. It
>sounds like C++ has intrinsic functions in all but name; maybe it's
>time to take that last step and remove that nominal distinction.
There is no step to take. The C++ library isnt a library
of functions and classes. It is an intrinsic part of the language.
It is simply described "as if" it were a library to make that
part of the language easy to specify and make consistent.
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd,
81A Glebe Point Rd, GLEBE Mem: SA IT/9/22,SC22/WG21
NSW 2037, AUSTRALIA Phone: 61-2-566-2189
Author: sjc@netcom.com (Steven Correll)
Date: Thu, 11 Aug 1994 05:57:54 GMT Raw View
>In article <3293dg$4f5@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:
>> ...The C++ rule is
>> that you cannot safely write your own declarations for library functions.
>> You have to include the appropriate header...
In article <MATT.94Aug9172510@physics2.berkeley.edu>,
Matt Austern <matt@physics.berkeley.edu> wrote:
>I'm wondering, then: if, regardless of whether my program contains the
>line "#include <math.h>", I'm unable to define my own function
>::sin(double), then does it serve any useful purpose to require my
>program to contain that line? If the compiler already knows enough
>about ::sin(double) so that my redefinition would break things,
>then why should I have to tell it about that function again?
>
>...It sounds like C++ has intrinsic functions in all but name; maybe it's
>time to take that last step and remove that nominal distinction.
The tradition of letting the user replace library functions died back in 1989
when the ANSI C standard reserved all identifiers defined by the library (ANSI
X3.159-1989 section 4.1.2.1). The rationale says that the committee worried not
only that one library function might call another, but also that library
functions might be bundled together so that you couldn't import one without
getting others along with it. In either case, the compiler might not know
anything about "sin", but the library implementation would know enough that
redefinition would break things.
The standard and rationale together suggest the committee was trying to hew a
delicate line between implementors who wanted the advantages of Fortran-like
intrinsics (for optimization, error-checking, etc.) and those who wanted to
save effort by implementing the library via ordinary macros and functions.
Section 4.1.6 shows how #include and #undef interact to enable and disable
compiler optimizations (e.g. macro-izing, inlining, or using a special calling
sequence). Because the compiler may treat #include as a special directive
instead of inserting an actual header file, the slightly convoluted rules
appear to permit an intrinsic implementation.
How much of this machinery survives in the current C++ draft? Is there any
problem (apart from adding work for implementors) with the quoted proposal?
--
Steven Correll == PO Box 66625, Scotts Valley, CA 95067 == sjc@netcom.com
Author: JdeBP@osmium.jba.co.uk (Jonathan de Boyne Pollard)
Date: 8 Aug 1994 13:51:01 GMT Raw View
>>But the string class isn't being built into the language! It's going
>>to be built into the standard class library.
>
> It's fuzzy because it's a distinction without a difference. The string
>class is part of C++. Its specification lives in a chapter entitled "Library"
>rather than, say, a chapter entitled "Expression". Other than having to look
>in the right chapter of the standard, I can't see how this makes any difference
>whatsoever to a user of the language.
The difference is concrete (to this C++ user, at least). If you
don't include the appropriate standard header, you can easily
construct your own basic_string<T> (or whatever) class and use that,
the same as you can rewrite malloc(), or replace iostreams.
Compare library features such as these to *language* features, such
as bool or wchar_t.
As an aside, this makes an interesting argument against wchar_t
being a keyword rather than a typedef. With a compiler that doesn't
implement wchar_t well (the DOS compilers that I've used did not) it
will be impossible to correct.
I'm a "long char" man myself ...
JdeBP
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 9 Aug 1994 16:42:38 GMT Raw View
In article ofo@silver.jba.co.uk, JdeBP@osmium.jba.co.uk (Jonathan de Boyne Pollard) writes:
>
>The difference is concrete (to this C++ user, at least). If you
>don't include the appropriate standard header, you can easily
>construct your own basic_string<T> (or whatever) class and use that,
>the same as you can rewrite malloc(), or replace iostreams.
Not quite. For one thing, you can't (legally) replace malloc itself.
Its name is reserved whether you include any standard headers or not.
The same is true for most of the C++ library.
The reason is that parts of the standard library may rely on other parts
of the library. Arbitrary replacement of external names may break
library code. Similarly, if you introduce your own class with the
same name as a standard library class, you could cause a conflict with
library code; those names have to be reserved.
There are some special exemptions. You are allowed to replace the global
operator new and operator delete, but you have to conform to specified
semantics.
So there really is not much distinction in practical terms between a
"language rule" and a "library rule".
---
Steve Clamage, stephen.clamage@eng.sun.com
Author: haubert@ed8200.ped.pto.ford.com (Phil Haubert)
Date: Tue, 9 Aug 1994 20:42:53 GMT Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
: In article ofo@silver.jba.co.uk, JdeBP@osmium.jba.co.uk (Jonathan de Boyne Pollard) writes:
: >
: >The difference is concrete (to this C++ user, at least). If you
: >don't include the appropriate standard header, you can easily
: >construct your own basic_string<T> (or whatever) class and use that,
: >the same as you can rewrite malloc(), or replace iostreams.
: Not quite. For one thing, you can't (legally) replace malloc itself.
: Its name is reserved whether you include any standard headers or not.
: The same is true for most of the C++ library.
That isn't a language restriction. It's a combination of the 'C' linker,
libc, and 'C' linkage.
: The reason is that parts of the standard library may rely on other parts
: of the library. Arbitrary replacement of external names may break
: library code. Similarly, if you introduce your own class with the
: same name as a standard library class, you could cause a conflict with
: library code; those names have to be reserved.
Putting the standard libraries in a separate namespace implies two
versions of each: one with 'C' linkage and one with C++ linkage.
Is that correct?
: So there really is not much distinction in practical terms between a
: "language rule" and a "library rule".
Well, if its in a library at least you have a chance of replacing it.
If you just want your own code to be affected it should be just a
matter of a 'using' statement.
phil
Author: matt@physics2.berkeley.edu (Matt Austern)
Date: 10 Aug 1994 00:25:10 GMT Raw View
In article <3293dg$4f5@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:
> No. It is up to the implementation how to handle it. The C++ rule is
> that you cannot safely write your own declarations for library functions.
> You have to include the appropriate header to be assured of the program
> working.
Hm. I didn't realize that standard library functions were quite that
special; I guess I was too used to the traditional idea that they're
no different than functions in any old user-defined library.
I'm wondering, then: if, regardless of whether my program contains the
line "#include <math.h>", I'm unable to define my own function
::sin(double), then does it serve any useful purpose to require my
program to contain that line? If the compiler already knows enough
about ::sin(double) so that my redefinition would break things,
then why should I have to tell it about that function again?
Or, to put it slightly differently: if the line between the language
and the library has gotten this blurry, maybe it makes more sense to
erase that line altogether. FORTRAN has the notion of "intrinsic
functions", predefined functions that are part of the language. It
sounds like C++ has intrinsic functions in all but name; maybe it's
time to take that last step and remove that nominal distinction.
--
--matt
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 9 Aug 1994 23:27:44 GMT Raw View
In article 3837@ed8200.ped.pto.ford.com, haubert@ed8200.ped.pto.ford.com (Phil Haubert) writes:
>Steve Clamage (clamage@Eng.Sun.COM) wrote:
>
>: Not quite. For one thing, you can't (legally) replace malloc itself.
>: Its name is reserved whether you include any standard headers or not.
>: The same is true for most of the C++ library.
>
>That isn't a language restriction. It's a combination of the 'C' linker,
>libc, and 'C' linkage.
If you are going to post answers in a 'std' group, I recommend you read
the standard first. It IS a language restriction. Look it up. (It is a
language restriction in the C standard, and also in the C++ working document.)
>Putting the standard libraries in a separate namespace implies two
>versions of each: one with 'C' linkage and one with C++ linkage.
>Is that correct?
No. It is up to the implementation how to handle it. The C++ rule is
that you cannot safely write your own declarations for library functions.
You have to include the appropriate header to be assured of the program
working. The standard allows implementors enough leeway to do something
sensible in a convenient way.
---
Steve Clamage, stephen.clamage@eng.sun.com
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 10 Aug 1994 23:41:51 GMT Raw View
In article 94Aug9172510@physics2.berkeley.edu, matt@physics2.berkeley.edu (Matt Austern) writes:
>
>Hm. I didn't realize that standard library functions were quite that
>special; I guess I was too used to the traditional idea that they're
>no different than functions in any old user-defined library.
Well, that's what makes them "standard". They have required semantics
which the C/C++ implementor and users may rely on. If you want to replace
them, you have to step outside what is guaranteed to work. An implementation
is allowed to document how you can replace them if you want to, or you
could reverse-engineer the impelentation. It may work just fine, but all
bets are off when you move to a different system, even on the same machine.
Again, that's the difference between "standard" and "roll your own."
>I'm wondering, then: if, regardless of whether my program contains the
>line "#include <math.h>", I'm unable to define my own function
>::sin(double), then does it serve any useful purpose to require my
>program to contain that line?
If you do not include <math.h>, you can define your own function
static double sin(double);
at file scope. You just can't make it extern. Is this useful? Maybe
not, as this is a bug waiting to happen.
>Or, to put it slightly differently: if the line between the language
>and the library has gotten this blurry, maybe it makes more sense to
>erase that line altogether. FORTRAN has the notion of "intrinsic
>functions", predefined functions that are part of the language. It
>sounds like C++ has intrinsic functions in all but name; maybe it's
>time to take that last step and remove that nominal distinction.
I tend to agree, but it probably won't happen.
---
Steve Clamage, stephen.clamage@eng.sun.com