This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
gcc 3.0 and <strstream>
- To: gcc at gcc dot gnu dot org
- Subject: gcc 3.0 and <strstream>
- From: Peter Scott <drip at cats dot ucsc dot edu>
- Date: Tue, 07 Aug 2001 20:30:36 -0700
- cc: blufox at cats dot ucsc dot edu
dear people:
i am updating a few small programs we use here in the
physics curriculum, and trying to learn g++ as i do so (i am
not an experienced C++ (g++) programmer). i have both
gcc-2.95.3 and gcc-3.0 installed on my red hat linux 6.1
machine, as obtained from you. [the building and
installation was flawless as far as i could tell---thank you!]
while i notice that g++-3.0 does things that g++-2.95.3 (or
g++-2.95.2) does not do (e.g., the "at()" function is now in
3.0), 3.0 seems significantly slower on my machine, and it
does not like "old" code that uses istrstream (from <strstream>).
hence i am at the moment preferring 2.95.3 to 3.0.
i append the results from some tests, from compiling
stroustrup's `dc_command_line.c', as obtained from
http://www.research.att.com/~bs/dc_command_line.c
any comments would be most welcome.
thanks,
-- peter
----------------------------------------------------------------
ONE:
result of `repeat 4 time g++ -Wall dc_command_line.c'
for g++ version 2.95.3 on redhat 6.1 linux with 450 MHz clock
(with stroustrup's downloaded code, which uses istrstream from <strstream>)
1.650u 0.130s 0:01.78 100.0% 0+0k 0+0io 1390pf+0w
1.710u 0.080s 0:01.80 99.4% 0+0k 0+0io 1390pf+0w
1.740u 0.040s 0:01.79 99.4% 0+0k 0+0io 1390pf+0w
1.700u 0.080s 0:01.79 99.4% 0+0k 0+0io 1390pf+0w
----------------------------------------------------------------
TWO:
result of `repeat 4 time g++ -Wall dc_command_line.c'
for g++ version 3.0 on redhat linux 6.1 with 450 MHz clock:
(i changed the code to use istringstream from <sstream>)
5.990u 0.220s 0:07.33 84.7% 0+0k 0+0io 1906pf+0w
5.910u 0.150s 0:06.08 99.6% 0+0k 0+0io 1600pf+0w
6.010u 0.080s 0:06.10 99.8% 0+0k 0+0io 1600pf+0w
5.910u 0.140s 0:06.06 99.8% 0+0k 0+0io 1600pf+0w
notes: (a) stroustrup's downloaded code does not work with 3.0.
(b) 3.0 takes roughly 3.5 times longer to compile than 2.95.3.
----------------------------------------------------------------
THREE:
result of `repeat 4 time g++ -Wall dc_command_line.c'
for g++ version 2.95.3 with stroustrup's (changed) code using
istringstream from <sstream>
1.810u 0.130s 0:01.95 99.4% 0+0k 0+0io 1406pf+0w
1.870u 0.050s 0:01.92 100.0% 0+0k 0+0io 1404pf+0w
1.810u 0.110s 0:01.92 100.0% 0+0k 0+0io 1404pf+0w
1.780u 0.150s 0:01.94 99.4% 0+0k 0+0io 1404pf+0w
(this is slightly slower than trial ONE above, but not much)
i append stroustrup's dc_command_line.c code as downloaded
from his website:
=====================================================================
// The desk calulator
// includes character-level input (sec6.1.3) and
// command line input (sec6.1.7),
// but no namespaces and
// no exceptions
// pp 107-119, sec 6.1, A Desk Calculator
// uses += rather than push_back() for string
// to work around standard library bug
// uses istrstream from <strstream> rather than istringstream from <sstream>
// to work around standard library bug
// No guarantees offered. Constructive comments to bs@research.att.com
/*
program:
END // END is end-of-input
expr_list END
expr_list:
expression PRINT // PRINT is semicolon
expression PRINT expr_list
expression:
expression + term
expression - term
term
term:
term / primary
term * primary
primary
primary:
NUMBER
NAME
NAME = expression
- primary
( expression )
*/
#include <string>
#include <cctype>
#include<iostream>
#include<map>
//#include<sstream> // string streams
#include<strstream> // C-style string streams
using namespace std;
istream* input; // pointer to input stream
int no_of_errors; // note: default initialized to 0
double error(const char* s)
{
no_of_errors++;
cerr << "error: " << s << '\n';
return 1;
}
enum Token_value {
NAME, NUMBER, END,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')'
};
Token_value curr_tok = PRINT;
double number_value;
string string_value;
Token_value get_token()
{
char ch;
do { // skip whitespace except '\en'
if(!input->get(ch)) return curr_tok = END;
} while (ch!='\n' && isspace(ch));
switch (ch) {
case ';':
case '\n':
return curr_tok=PRINT;
case '*':
case '/':
case '+':
case '-':
case '(':
case ')':
case '=':
return curr_tok=Token_value(ch);
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
input->putback(ch);
*input >> number_value;
return curr_tok=NUMBER;
default: // NAME, NAME=, or error
if (isalpha(ch)) {
string_value = ch;
while (input->get(ch) && isalnum(ch))
string_value += ch; // string_value.push_back(ch);
// to work around library bug
input->putback(ch);
return curr_tok=NAME;
}
error("bad token");
return curr_tok=PRINT;
}
}
map<string,double> table;
double expr(bool); // cannot do without
double prim(bool get) // handle primaries
{
if (get) get_token();
switch (curr_tok) {
case NUMBER: // floating-point constant
{ double v = number_value;
get_token();
return v;
}
case NAME:
{ double& v = table[string_value];
if (get_token() == ASSIGN) v = expr(true);
return v;
}
case MINUS: // unary minus
return -prim(true);
case LP:
{ double e = expr(true);
if (curr_tok != RP) return error(") expected");
get_token(); // eat ')'
return e;
}
default:
return error("primary expected");
}
}
double term(bool get) // multiply and divide
{
double left = prim(get);
for (;;)
switch (curr_tok) {
case MUL:
left *= prim(true);
break;
case DIV:
if (double d = prim(true)) {
left /= d;
break;
}
return error("divide by 0");
default:
return left;
}
}
double expr(bool get) // add and subtract
{
double left = term(get);
for (;;) // ``forever''
switch (curr_tok) {
case PLUS:
left += term(true);
break;
case MINUS:
left -= term(true);
break;
default:
return left;
}
}
int main(int argc, char* argv[])
{
switch (argc) {
case 1: // read from standard input
input = &cin;
break;
case 2: // read argument string
// input = new istringstream(argv[1]);
input = new istrstream(argv[1]);
break;
default:
error("too many arguments");
return 1;
}
table["pi"] = 3.1415926535897932385; // insert predefined names
table["e"] = 2.7182818284590452354;
while (*input) {
get_token();
if (curr_tok == END) break;
if (curr_tok == PRINT) continue;
cout << expr(false) << '\n';
}
if (input != &cin) delete input;
return no_of_errors;
}