R. Clayton (rclayton@clayton.cs.monmouth.edu)
(no date)
I found that g++ in these two platform are different even though I used the
same arguments as you used to compile the files.
For example, I want to set the cout to display the float in fixed format. I
used 'fixed' manipulator on SOLARIS, but there is no 'fixed' on LINUX. Then I
use setf() function of cout. But they are still different:
On SOLARIS:
#include <ios>
cout.setf(ios_base::fixed, ios_base::floatfield);
On LINUX:
#include <streambuf>
cout.setf(ios::fixed, ios::floatfield);
The important thing to remember is that you're dealing with the standard c++
library. That has several consiquences, which the code fragments don't deal
with, and that's causing all the problems.
But first, I'm not sure how to interpret the code fragments. In particular,
neither of them work on the respective hosts:
cl uname -s
SunOS
cl cat s.cc
#include <ios>
int main() {
cout.setf(ios_base::fixed, ios_base::floatfield);
}
cl g++ -c s.cc
s.cc: In function `int main()':
s.cc:4: `cout' undeclared (first use this function)
s.cc:4: (Each undeclared identifier is reported only once for each function
it appears in.)
s.cc:4: `ios_base' undeclared (first use this function)
s.cc:4: parse error before `::' token
cl
ro uname -s
Linux
ro cat l.cc
#include <streambuf>
int main() {
cout.setf(ios::fixed, ios::floatfield);
}
ro g++ -c l.cc
l.cc: In function `int main()':
l.cc:4: `cout' undeclared (first use this function)
l.cc:4: (Each undeclared identifier is reported only once for each function
it appears in.)
l.cc:4: `ios' undeclared (first use this function)
l.cc:4: parse error before `::' token
ro
Even though I don't understand the code fragments, their error messages give
several valuable clues. First, cout is undefined, which you would expect
because cout is defined in <iostream>, which the code doesn't include:
cl cat s.cc
#include <ios>
#include <iostream>
int main() {
cout.setf(ios_base::fixed, ios_base::floatfield);
}
cl g++ -c s.cc
s.cc: In function `int main()':
s.cc:5: `cout' undeclared (first use this function)
s.cc:5: (Each undeclared identifier is reported only once for each function
it appears in.)
s.cc:5: `ios_base' undeclared (first use this function)
s.cc:5: parse error before `::' token
cl
But cout is still undefined. Here's where the standard c++ library comes in.
Because the iostream system is part of the standard c++ library, it is, like
all parts of the standard c++ library, part of the std name space. Dealing
with that in the code gives:
cl cat s.cc
#include <ios>
#include <iostream>
int main() {
std::cout.setf(ios_base::fixed, ios_base::floatfield);
}
cl g++ -c s.cc
s.cc: In function `int main()':
s.cc:5: `ios_base' undeclared (first use this function)
s.cc:5: (Each undeclared identifier is reported only once for each function
it appears in.)
s.cc:5: parse error before `::' token
cl
That takes care of cout, but what about ios_base? It's the same story:
ios_base is part of the io stream library, which is part of the standard
c++ library, which is in the std namespace. Dealing with that in the code
gives
cl cat s.cc
#include <ios>
#include <iostream>
int main() {
std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
}
cl g++ -c -ansi -pedantic -Wall s.cc
cl
That fixes up the problem (on solaris, anyway), but the code still needs to
be cleaned up a bit. In class I briefly sketched the bottom half of the file
stream class hierarchy; now we have to look at the upper half of the stream
class hierarchy:
ios_base
|
|
ios
/ \
/ \
istream ostream
\ /
\ /
iostream
The first thing to note about this diagram is that it's not right. The
stream hierarchy actually constists of template classes (except for
ios_base); what I've shown here is the instantiations of the template classes
for the basic c++ type char.
The second thing to note, although it's difficult to see in this diagram, is
that ios is a specialization of ios_base for the char template parameter.
Some of the things defined in ios_base may be redefined in ios to make them
appropriate for the char data type. You should use ios:: rather than
ios_base:: to access stream entities to make sure you're accessing the right
entities. In this case it probably doesn't make any difference because
you're accessing bit flags, which don't need to change from one data type to
the next, but other entities may change depending on the template parameter
type.
The third thing to note is that iostream has ios has a parent, so it's
unnecessary to include ios explicitly if you include iostream (and there's no
reason to just include ios). This may seem a trivial point, but it's not:
good programmers write code that can be easily changed, and changing one
thing (for example, changing iostream to wiostream) is easier than changing
two things (for example, changing both iostream and ios to wiostream and
wios).
What we're left with is some small, compact code that's standards conformant
(I hope), which means it should be compilable on any standards conformant
compiler, whether it be on solaris
cl cat s.cc
#include <iostream>
int main() {
std::cout.setf(std::ios::fixed, std::ios::floatfield);
}
cl g++ -c -ansi -pedantic -Wall s.cc
cl CC -c s.cc
cl
or linux
ro g++ -c -ansi -pedantic -Wall s.cc
ro
This archive was generated by hypermail 2.0b3 on Fri May 10 2002 - 12:45:04 EDT