 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Arturo DiDonna Guest
|
Posted: Tue Mar 02, 2004 11:29 am Post subject: Compiling problems with g++ |
|
|
I posted this message also to the unmoderated list. I apologize in
advance to people that will read it twice.
==============================
Hello everyone. I am trying to compile someone else code and I am
stuck with compilation problems using
the g++ 3.3 compiler. Basically, when compiling the following code, I
get this error message:
parsefcns.cc: In function `void get_token(std::ifstream*, char**)':
parsefcns.cc:57: error: cannot convert `std::basic_string<char,
std::char_traits' to `char*' in
assignment
make: *** [parsefcns.o] Error 1
I don't know C++ and I was wondering if there was a kind soul willing
to help me in solving this problem.
Thanks in advance.
Arturo
...........................................
#include <fstream>
#include <sstream>
#include <cctype>
#include <cstring>
#include <iostream>
using namespace std;
using std::ifstream;
using std::ostringstream;
void get_token(std::ifstream *f_stream, char **ch_ptr)
{
char ch;
std::ostringstream buffer;
while( (f_stream->get(ch)) &&
(!isspace(ch)) &&
(!f_stream->eof()) )
{
buffer << ch;
}
buffer << ' ';
(*ch_ptr) = buffer.str(); // This is the line giving compilation
problems
// return ch;
f_stream->seekg(-1, std::ios::cur);
}
.............etc.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Tue Mar 02, 2004 2:07 pm Post subject: Re: Compiling problems with g++ |
|
|
In message <ba2fb238.0403011154.37983e34 (AT) posting (DOT) google.com>, Arturo
DiDonna <arturo_didonna (AT) yahoo (DOT) it> writes
| Quote: | void get_token(std::ifstream *f_stream, char **ch_ptr)
{
char ch;
std::ostringstream buffer;
while( (f_stream->get(ch)) &&
(!isspace(ch)) &&
(!f_stream->eof()) )
{
buffer << ch;
}
buffer << ' ';
(*ch_ptr) = buffer.str(); // This is the line giving compilation
problems
|
The type of *ch_ptr is char*, the type of buffer.str() is std::string
and your code is a perfect example of why WG21 avoided providing an
implicit conversion from std::string to char*. Had it foolishly done so
your code would have compiled without diagnostic and then blown up.
buffer is a local variable, and its internals will disappear on exit
from the function with the result that you will turn the argument bound
to ch_ptr at the call site into a hanging pointer.
Deducing your intent, I would rewrite your code as:
std::string get_token(std::ifstream source){
std::ostringstream token;
// process
return token.str();
}
And at the call site I would declare a strictly block scope variable:
std::string const token(get_token(file));
and then use:
token.c_str();
I can think of several variants on the theme but the basic principle is
to delay conversion to char* until it is essential.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Frédéric Lachasse Guest
|
Posted: Wed Mar 03, 2004 11:48 am Post subject: Re: Compiling problems with g++ |
|
|
"Arturo DiDonna" <arturo_didonna (AT) yahoo (DOT) it> wrote
| Quote: | I posted this message also to the unmoderated list. I apologize in
advance to people that will read it twice.
==============================
Hello everyone. I am trying to compile someone else code and I am
stuck with compilation problems using
the g++ 3.3 compiler. Basically, when compiling the following code, I
get this error message:
parsefcns.cc: In function `void get_token(std::ifstream*, char**)':
parsefcns.cc:57: error: cannot convert `std::basic_string<char,
std::char_traits' to `char*' in
assignment
make: *** [parsefcns.o] Error 1
I don't know C++ and I was wondering if there was a kind soul willing
to help me in solving this problem.
Thanks in advance.
Arturo
..........................................
#include <fstream
#include
#include
#include
#include
using namespace std;
using std::ifstream;
using std::ostringstream;
void get_token(std::ifstream *f_stream, char **ch_ptr)
{
char ch;
std::ostringstream buffer;
while( (f_stream->get(ch)) &&
(!isspace(ch)) &&
(!f_stream->eof()) )
{
buffer << ch;
}
buffer << ' ';
(*ch_ptr) = buffer.str(); // This is the line giving compilation
problems
// return ch;
f_stream->seekg(-1, std::ios::cur);
}
|
This looks bad. It seems to me this piece of code was probably ported from a
pre-ansi version using old iostream library. It will work if you use
std::ostrstream instead of std::ostringstream. Of course, you need to check
that the returned ch_ptr is freed using delete[].
So: replace
include <sstream>
by
include <strstream>
and all reference to ostringtream by ostrstream.
A better way would be to return a std::string instead of a char*, but that
probably means more modifications in the source.
Note: ostrstream is supposed to be deprecated in the current ANSI C++
standard, but I understand that next revision of the standard may remove the
deprecated status.
--
Frédéric Lachasse - ECP86
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Wed Mar 03, 2004 8:24 pm Post subject: Re: Compiling problems with g++ |
|
|
In message <tHa1c.29241$TF2.4325 (AT) nwrdny02 (DOT) gnilink.net>, Frédéric
Lachasse <frederic.lachasse (AT) verizon (DOT) net> writes
| Quote: | void get_token(std::ifstream *f_stream, char **ch_ptr)
{
char ch;
std::ostringstream buffer;
while( (f_stream->get(ch)) &&
(!isspace(ch)) &&
(!f_stream->eof()) )
{
buffer << ch;
}
buffer << ' ';
(*ch_ptr) = buffer.str(); // This is the line giving compilation
problems
// return ch;
f_stream->seekg(-1, std::ios::cur);
}
This looks bad. It seems to me this piece of code was probably ported from a
pre-ansi version using old iostream library. It will work if you use
std::ostrstream instead of std::ostringstream. Of course, you need to check
that the returned ch_ptr is freed using delete[].
So: replace
include
by
include
and all reference to ostringtream by ostrstream.
A better way would be to return a std::string instead of a char*, but that
probably means more modifications in the source.
Note: ostrstream is supposed to be deprecated in the current ANSI C++
standard, but I understand that next revision of the standard may remove the
deprecated status.
|
Yes, ostrstream does use an array of char but consider how it gets that
array; by using new to allow for expansion or by using a fixed buffer.
Now note how that leaves the onus on the programmer to track who owns
the buffer and who is responsible for releasing it.
Using ostrstream and then passing out its buffer to a remote site is a
recipe for either hanging pointers, resource leaks or wrongly trying to
delete memory that was not provided dynamically.
I do not think ostrstream is an appropriate type in the context of the
above function.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Old Wolf Guest
|
Posted: Thu Mar 04, 2004 9:56 pm Post subject: Re: Compiling problems with g++ |
|
|
| Quote: | void get_token(std::ifstream *f_stream, char **ch_ptr)
{
char ch;
std::ostringstream buffer;
while( (f_stream->get(ch)) &&
(!isspace(ch)) &&
(!f_stream->eof()) )
{
buffer << ch;
}
buffer << ' ';
(*ch_ptr) = buffer.str(); // This is the line giving compilation
problems
Deducing your intent, I would rewrite your code as:
std::string get_token(std::ifstream source){
std::ostringstream token;
// process
return token.str();
}
|
You cannot pass streams by value, better is:
std::string get_token(std::ifstream &source){
(For the OP's benefit .. I'm sure this was just a typo)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Thu Mar 04, 2004 10:05 pm Post subject: Re: Compiling problems with g++ |
|
|
Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk> wrote
| Quote: | In message <tHa1c.29241$TF2.4325 (AT) nwrdny02 (DOT) gnilink.net>, Frédéric
Lachasse <frederic.lachasse (AT) verizon (DOT) net> writes
void get_token(std::ifstream *f_stream, char **ch_ptr)
{
char ch;
std::ostringstream buffer;
while( (f_stream->get(ch)) &&
(!isspace(ch)) &&
(!f_stream->eof()) )
{
buffer << ch;
}
buffer << ' ';
(*ch_ptr) = buffer.str(); // This is the line giving compilation
problems
// return ch;
f_stream->seekg(-1, std::ios::cur);
}
This looks bad. It seems to me this piece of code was probably ported
from a pre-ansi version using old iostream library. It will work if
you use std::ostrstream instead of std::ostringstream. Of course, you
need to check that the returned ch_ptr is freed using delete[].
So: replace
include
by
include
and all reference to ostringtream by ostrstream.
A better way would be to return a std::string instead of a char*, but
that probably means more modifications in the source.
Note: ostrstream is supposed to be deprecated in the current ANSI C++
standard, but I understand that next revision of the standard may
remove the deprecated status.
Yes, ostrstream does use an array of char but consider how it gets
that array; by using new to allow for expansion or by using a fixed
buffer. Now note how that leaves the onus on the programmer to track
who owns the buffer and who is responsible for releasing it.
Using ostrstream and then passing out its buffer to a remote site is a
recipe for either hanging pointers, resource leaks or wrongly trying
to delete memory that was not provided dynamically.
I do not think ostrstream is an appropriate type in the context of the
above function.
|
Yes and no. Obviously, if you are designing a new system, changing the
function to return an std::string, and using std::ostringstream in the
function, is the only way to go. If you are interfacing with a legacy
interface, which you cannot change, you may not have that luxury.
Even when interfacing with a legacy interface, of course, the rest of
your comment is valid -- you really must pay a incredibly lot of
attention concerning who owns what, and how. Thus, for example, if you
simply return the return value of strstream::str(), the caller is
responsible for deleting it. With a delete[], not a free -- if the
legacy interface involves C, you will very quickly end up with undefined
behavior of the worst king, that which seems to work with most
implementations, most of the time.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|