Topic: iostream changes
Author: miker3@ix.netcom.com (Mike Rubenstein)
Date: 1997/09/15 Raw View
kuehl@horn.informatik.uni-konstanz.de (Dietmar Kuehl) wrote:
> Hi,
> Mike Rubenstein (miker3@ix.netcom.com) wrote:
> : bs@research.att.com (Bjarne Stroustrup) wrote:
> : > #include<iostream>
> : >
> : > int main()
> : > {
> : > std::cout << "Hello, world\n";
> : > }
>
> : the example you give. Even there, it gives a warning and it is
> : questionable whether the program produced executes as required by the
> : standard (it returns a nonzero return code to the command processor
> : instead of 0 which is normally used for successful execution under
> : Windows NT).
>
> Just note, that the program posted by Bjarne Stroustrup is standard
> conformant *AND* returns EXIT_SUCCESS (which is defined to be 0). That
> is, it is completely correct. According to the standard, that is... The
> point here is the special exception for the function 'main()' saying
> that floating off the end of the function 'main()' is equivalent to
> exiting the function with 'return 0;'. However, this is a special
> exception holding only for 'main()'. Floating off the end of any other
> function returning something different than 'void' resutls in undefined
> behavior.
Generally correct, but one nit to pick: EXIT_SUCCESS is not
necessarily defined to be 0. return from main or exit with either
EXIT_SUCCESS or 0 returns an implementation-defined status indicating
successful termination, but they are not required to be identical (and
there may be other values that can be returned to indicate successful
termination). The draft says nothing about whether different values
used for successful termination are distinguishable.
My point in saying it was questionable whether Microsoft complies with
the standard was based on the fact that there is no requirement that 0
actually be returned to the host environment if main returns 0. In
fact, there are systems in which that should not be done since 0
normally means unsuccessful termination; on such systems the run time
must change the returned value to something appropriate.
The implementor is free to define anything he likes as "successful
termination." However, it's obvious that the intent is that it be
defined in a way that is consistent with the usual operating system
conventions, which on Windows NT means that 0, and only 0, indicates
successful termination.
The implementation's definition of "successful implementation" is
really a quality of implementation issue -- a Windows NT
implementation that defines it as anything but returning 0 is poor in
that regard.
Implementation-defined behavior must be documented. I can find
nothing on successful termination in Microsoft's section on
implementation-defined behavior, but the documentation for exit
clearly indicates that the argument (or the returned value from main)
is actually returned to the operating system and seems to say that 0
is the only value for successful termination.
I'd say that given Microsoft's documentation, the translation of the
program does not comply with the standard, but someone who is kinder
might say that it does but is very poorly implemented; I can't think
of anything kinder one might say.
Michael M Rubenstein
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Steve Clamage <stephen.clamage_nospam@Eng.Sun.COM>
Date: 1997/09/11 Raw View
Joe Buck wrote:
>
> Ironic, isn't it? The committee worked very hard to make traditional
> C programs continue to compile, but felt free to break every traditional
> C++ program anyone has ever written (e.g. the traditional "Hello, world"
> program).
The "hello world" breakage is putting all the C++ standard library
into namespace std. If we had not put the library into its own
namespace, we would have been flamed to a crisp for making it
impossible to write portable programs because a programmer could
not know what additional names an implementor might have put into
the global namespace.
OTOH if you really do want the whole library in the global namespace,
you have that option. You can just put "using namespace std;"
in your project header file.
The C++ Committee agonized over the problem for writers of
introductory programming texts. It would be nice to be able
to present "hello world" without a "using" clause or double colons.
We couldn't find a way to make that feasible. One way for writers
to address the issue is the same way they address the mysterious
but necessary include directive: describe it as magic which will
be explained later.
> This point is made very effectively in Al Stevens' column in the September
> Dr. Dobbs Journal. He points out that the column writer has a dilemma:
> he can write standard C++, which no compiler on earth will accept, or
> he can write traditional C++, ...
Did he also mention that no possible C++ standard could allow
all (or even most) existing "traditional" C++ programs to compile?
C++ compilers have historically been different enough that programmers
have traditionally complained at being unable to write a real-
world program that worked unchanged across different implementations.
Would Stevens now have us believe that all the previous complaining was
unfounded, that programmers routinely wrote perfectly portable
programs, and the standard only now causes programs to break?
> He also has some suggestions for implementers as to
> how they can limit the damage: e.g. <iostream.h> includes <iostream>
> and also does "using namespace std;" so that "Hello, world" still works.
That is a truly bad suggestion. You would then have only two
choices: leave iostreams in namespace standard, or put the entire
C++ library in the global namespace, even those portions you
didn't want to collide with other parts of your
program. (String classes come to mind.)
A better idea is for the vendor to provide an <iostream.h> header
which puts only the iostream names into the global namespace. You do
that with individual using-declarations, not with the sledgehammer
of "using namespace std;". I would expect vendors to provide a header
along those lines so that their customers would have a smooth
transition to standard C++.
> It would be nice if all vendors would do such things in the same way.
Aye, there's the rub.
The problem is that different vendors implemented the iostream
headers in different ways, using differently-named headers
partitioned differently. For example, some vendors used
".h" suffixes, some used ".hxx" or ".H" or ".hh" or ".h++".
Sometimes the specialized headers like fstream included the basic
iosteam header and sometimes not. Sometimes the header names were
truncated to 8 characters and sometimes not.
No matter what extra compatibility headers the standard mandated,
it would cause problems or be a waste of effort for users (and
vendors) on some important systems. Instead of requiring extra
features that might be counter-productive, the standard does
two positive things:
1. It mandates a standard form which all systems must support.
2. It allows vendors to provide their own compatibilty-mode
headers and compilers to provide a smoother transition for
their customers. (Old code will continue to work.)
It would have been nice to specify something that would have
allowed all programmers to continue to use their old code
and yet have it work unchanged across all standard-conforming
implementations. That was impossible.
The remainder of the changes in iostreams were required to
support internationalization. The classic iostream design
made it impossible to support wide characters or different
locales. A standard that did not support I18N could not have
passed any ISO (or ANSI) vote.
Programs using iostreams in a simple way (e.g. programs in
textbooks) will continue to work as written. Programmers
using more sophisticated iostream features will find that
some modification is necessary, often minor. Programmers
concerned with I18N will find that some of it comes for free,
compared to finding it impossible to do previously.
I sympathize with Al Stevens' problems trying to write about
C++ in a changing world. I claim his problems are no worse
with the advent of the standard than they were before. The
situation is analagous to writing about C in, say, 1989.
This too shall pass.
--
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: bs@research.att.com (Bjarne Stroustrup)
Date: 1997/09/11 Raw View
As part of a very nice posting about standardizing C++ and problems
with the "Hello, world!" program using iostreams, Steve Clamage writes
> I sympathize with Al Stevens' problems trying to write about
> C++ in a changing world. I claim his problems are no worse
> with the advent of the standard than they were before. The
> situation is analagous to writing about C in, say, 1989.
> This too shall pass.
Indeed, consider the famous program from K&R1:
main()
{
printf("Hello, world!\n");
}
The ANSI C committe - very reluctantly - broke it. They had to to get a language
that was consistent, efficient, and sufficiently portable. They broke it by
requiring that a varadic function, such as printf, had to be declared before
it was used. Thus, every C programmer had to add
#include <stdio.h>
to this program (adding 25% in linecount and more than 33% in character count).
Was that a nuiscance? Yes, especially for textbook writers and students.
Did the requirement improve the language to the benefit of the users? Yes.
Amazing how history repeats itself.
Wellcome to the world of:
#include<iostream>
int main()
{
std::cout << "Hello, world\n";
}
Soon it will work everywhere. Being a sufferer myself, I too sympatize with
people who have trouble with inconsistent implementations, but as Steve said:
"This too shall pass," and we will all benefit in the slightly longer run.
- Bjarne
Bjarne Stroustrup, AT&T Labs, http://www.research.att.com/~bs
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: miker3@ix.netcom.com (Mike Rubenstein)
Date: 1997/09/12 Raw View
bs@research.att.com (Bjarne Stroustrup) wrote:
>
> As part of a very nice posting about standardizing C++ and problems
> with the "Hello, world!" program using iostreams, Steve Clamage writes
>
> > I sympathize with Al Stevens' problems trying to write about
> > C++ in a changing world. I claim his problems are no worse
> > with the advent of the standard than they were before. The
> > situation is analagous to writing about C in, say, 1989.
> > This too shall pass.
>
> Indeed, consider the famous program from K&R1:
>
> main()
> {
> printf("Hello, world!\n");
> }
>
> The ANSI C committe - very reluctantly - broke it. They had to to get a language
> that was consistent, efficient, and sufficiently portable. They broke it by
> requiring that a varadic function, such as printf, had to be declared before
> it was used. Thus, every C programmer had to add
>
> #include <stdio.h>
>
> to this program (adding 25% in linecount and more than 33% in character count).
>
> Was that a nuiscance? Yes, especially for textbook writers and students.
> Did the requirement improve the language to the benefit of the users? Yes.
>
> Amazing how history repeats itself.
>
> Wellcome to the world of:
>
> #include<iostream>
>
> int main()
> {
> std::cout << "Hello, world\n";
> }
>
> Soon it will work everywhere. Being a sufferer myself, I too sympatize with
> people who have trouble with inconsistent implementations, but as Steve said:
> "This too shall pass," and we will all benefit in the slightly longer run.
But there's a difference between the C example you cite and the C++
example. While the C standard broke some existing programs, one could
fix this (in the example you give) simply by adding the #include. It
was not terribly difficult to write standard C programs that would
compile using most compilers that were available during the later
stages of C standardization.
I regularly use Microsoft VC++, Sun C++, and GNU C++. I also use
Borland C++ fairly frequently and Watcom C++ occasionally and have
used IBM xlC. Of those compilers, only one, Microsoft, will compile
the example you give. Even there, it gives a warning and it is
questionable whether the program produced executes as required by the
standard (it returns a nonzero return code to the command processor
instead of 0 which is normally used for successful execution under
Windows NT).
Even worse, I don't know of any way of writing a "hello world" program
using iostreams that complies with the draft and will compile on all
of those compilers. Microsoft is easy -- just add return 0; at the
end of your example and there is no question that it works. Borland
and Watcom are a bit tricky, though pretty easy. The best I've come
up with is
#include <iostream>
// namespace std {}
namespace std {}
using namespace std;
int main()
{
cout << "Hello, world\n";
return 0;
}
I'm afraid I've not come up with any way to do it usign the other
compilers.
Michael M Rubenstein
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kuehl@horn.informatik.uni-konstanz.de (Dietmar Kuehl)
Date: 1997/09/12 Raw View
Hi,
Mike Rubenstein (miker3@ix.netcom.com) wrote:
: bs@research.att.com (Bjarne Stroustrup) wrote:
: > #include<iostream>
: >
: > int main()
: > {
: > std::cout << "Hello, world\n";
: > }
: the example you give. Even there, it gives a warning and it is
: questionable whether the program produced executes as required by the
: standard (it returns a nonzero return code to the command processor
: instead of 0 which is normally used for successful execution under
: Windows NT).
Just note, that the program posted by Bjarne Stroustrup is standard
conformant *AND* returns EXIT_SUCCESS (which is defined to be 0). That
is, it is completely correct. According to the standard, that is... The
point here is the special exception for the function 'main()' saying
that floating off the end of the function 'main()' is equivalent to
exiting the function with 'return 0;'. However, this is a special
exception holding only for 'main()'. Floating off the end of any other
function returning something different than 'void' resutls in undefined
behavior.
--
<mailto:dietmar.kuehl@uni-konstanz.de>
<http://www.informatik.uni-konstanz.de/~kuehl/>
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Gary Maier <gmaier@parawave.com>
Date: 1997/09/02 Raw View
I've recently been trying to incorporate the new Standard C++ Library
iostream template class, especially fstream.
As I'm sure many of you already know, the new iostream classes are
substantially different than the "traditional" implementation; this
includes the ommission of several public methods (some of which I'd
found quite useful).
Of course, the first questions I must ask is: Why was this done? What
benefits accrue to the programmer? Why does the new public class API
differ so substantially from the original implementation?
The other, more pertinant question (at least, as far as my project is
concerned): How do I retrieve a handle to the underlying stream in an
fstream class -- either a FILE* or file descriptor (i.e. long)? The
"old" fstream class had a method, fd(), which made this possible.
Thanks for any help.
Gary Maier
gmaier@parawave.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kuehl@horn.informatik.uni-konstanz.de (Dietmar Kuehl)
Date: 1997/09/03 Raw View
Hi,
Gary Maier (gmaier@parawave.com) wrote:
: Of course, the first questions I must ask is: Why was this done?
Apart from the fact that IOStream became a template and now uses
locales, it was basically a cleanup. The former per-standard API was
not functionally equivalent to the standard API. Of course, there were
vendor specific extensions but these were never considered part of the
standard IOStream classes.
: What benefits accrue to the programmer?
Templatization and introduction of Locales were essential for I18N.
This may not be an important issue for Americans but it is relatively
important for the rest of the Western world, quite important for some
other nations, and essential for the Eastern world.
: Why does the new public class API
: differ so substantially from the original implementation?
It does not. Some names in 'streambuf' were fixed. Everything else
essentially remained unchanged (if you consider the instantiation for
'char' and ignore the locale interaction).
: The other, more pertinant question (at least, as far as my project is
: concerned): How do I retrieve a handle to the underlying stream in an
: fstream class -- either a FILE* or file descriptor (i.e. long)? The
: "old" fstream class had a method, fd(), which made this possible.
It was never part of standard IOStreams and it is IMO unlikely that it
ever will become part of standard IOStreams. Like I recently described,
a corresponding comment was received for CD2, considered in London and
rejected. The basic argumentation was this:
- fd() is impossible, since there are systems which do not have file
descriptors.
- the interaction between 'FILE*' and IOStreams is non-trivial if both
are used together (what should be buffered where and apppear when).
- it is *easy* to define a simple 'streambuf' sitting on top of 'FILE*'
with the semantics appropriate for a given project.
The last argument was basically the killer in the last minute: the
IOStreams/locales workgroup was very close to approve a possibility to
construct a 'filebuf' from a 'FILE*' and to obtain a 'FILE*' from
'filebuf'. However, this would have ruled some very neat
implementation possibilities for relatively minor benefit: It takes
about 100 lines of code to create a 'streambuf' (for 'char' only; it is
substantially more difficult to do it for other character types but
these are not supported for 'FILE*' anyway) on top of 'FILE*'. Code for
this can eg. be found in Plauger's "The Draft Standard C++ Library"
(Prentice Hall) and in libg++. However, there is no definition which
is really suitable in all situations. At least the workgroup was not able
to come up with a solution suitable in all situations.
--
<mailto:dietmar.kuehl@uni-konstanz.de>
<http://www.informatik.uni-konstanz.de/~kuehl/>
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jbuck@synopsys.com (Joe Buck)
Date: 1997/09/10 Raw View
gmaier@parawave.com writes:
>I've recently been trying to incorporate the new Standard C++ Library
>iostream template class, especially fstream.
>
>As I'm sure many of you already know, the new iostream classes are
>substantially different than the "traditional" implementation; this
>includes the ommission of several public methods (some of which I'd
>found quite useful).
Ironic, isn't it? The committee worked very hard to make traditional
C programs continue to compile, but felt free to break every traditional
C++ program anyone has ever written (e.g. the traditional "Hello, world"
program).
This point is made very effectively in Al Stevens' column in the September
Dr. Dobbs Journal. He points out that the column writer has a dilemma:
he can write standard C++, which no compiler on earth will accept, or
he can write traditional C++, and be flamed to death by the pedants.
He also has some suggestions for implementers as to
how they can limit the damage: e.g. <iostream.h> includes <iostream>
and also does "using namespace std;" so that "Hello, world" still works.
It would be nice if all vendors would do such things in the same way.
Every compiler vendor has to solve the migration problem: how to get
people to the standard but still compile old code. KAI has a good
article on their approach:
http://www.kai.com/C_plus_plus/v3.2/doc/migrate/index.html
It would be nice if the committee could produce some recommendations
so that different vendors take a similar approach.
>The other, more pertinant question (at least, as far as my project is
>concerned): How do I retrieve a handle to the underlying stream in an
>fstream class -- either a FILE* or file descriptor (i.e. long)? The
>"old" fstream class had a method, fd(), which made this possible.
But that feature has been gone for a long time: it's a cfront-specific
hack. How would you implement fd() on a system that doesn't have Unix
file descriptors.
The answer is that in general, there is no underlying stream. You can
do sync_with_stdio so that operations on the standard streams (cin/stdin,
cout/stdout,cerr/stderr) can be mixed, but that's about it. If your
project is exclusively Unix, you could use file descriptor magic
to attach one of the standard streams to your file, but that goes
beyond the standard.
--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
If you thought flashing ads on Web sites were annoying, wait till the Web
and your operating system are "seamlessly integrated" and watch the
pulsating promotional crud spill out over your desktop. -- Scott Rosenburg
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]