When compiling the latest stable release I get a few warnings on tinyxmlparser.cpp, I've checked against the latest CVS upload and their still there. I'll give the line numbers for the two versions like so:
[old] means the latest stable release
[new] means the latest commit in the cvs
All warnings are implicit type conversions that can be solved with static_cast, but some might have another way to avoid the type conversion entirely?
The warnings are:
..::[ WARNING 1 ]::..
warning C4244: 'argument' : conversion from 'std::basic_istream<_Elem,_Traits>::int_type' to 'char', possible loss of data
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
Line:
*tag += in->get();
[old] 177
[new] 306
..::[ WARNING 2 ]::..
warning C4244: 'argument' : conversion from 'int' to 'char', possible loss of data
Line:
*tag += c;
[old] 190
[new] 320
..::[ WARNING 3-5 ]::..
warning C4244: '+=' : conversion from 'int' to 'char', possible loss of data
The first two warnings, and possibly the last two, are indicative of a slightly inappropriate use of get(). In particular, the chance of the stream returning EOF is being ignored, and therefore the EOF character - if encountered - would get appended onto the data before the reading loop terminates. (Assuming there is a separate termination condition.)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Bear in mind that 'The function returns true if none of the stream's error flags are set'. And the only thing that can set those flags is a failed I/O operation, which in these cases is going to be a get() I believe. I heard that this is the case in C and C++ for the sake of efficiency (no hidden peek() calls to check the next operation will work).
Easiest to show this with an example:
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
fstream file("test.txt");
while (file.good())
{
int c = file.get();
cout << "Read character with value: " << c << endl;
}
return 0;
}
Create test.txt, fill it with a word or two, then watch the output. Look for the -1 at the end.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi!
When compiling the latest stable release I get a few warnings on tinyxmlparser.cpp, I've checked against the latest CVS upload and their still there. I'll give the line numbers for the two versions like so:
[old] means the latest stable release
[new] means the latest commit in the cvs
All warnings are implicit type conversions that can be solved with static_cast, but some might have another way to avoid the type conversion entirely?
The warnings are:
..::[ WARNING 1 ]::..
warning C4244: 'argument' : conversion from 'std::basic_istream<_Elem,_Traits>::int_type' to 'char', possible loss of data
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
Line:
*tag += in->get();
[old] 177
[new] 306
..::[ WARNING 2 ]::..
warning C4244: 'argument' : conversion from 'int' to 'char', possible loss of data
Line:
*tag += c;
[old] 190
[new] 320
..::[ WARNING 3-5 ]::..
warning C4244: '+=' : conversion from 'int' to 'char', possible loss of data
Lines:
*value += ( tolower( *(p+3) ) - 'a' + 10 );
[old] 241, 249 and 252
[new] gone?
..::[ WARNING 6 ]::..
warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
Line:
int tagIndex = tag->length();
[old] 397
[new] 561
..::[ WARNING 7 ]::..
warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
Line:
int tagIndex = tag->length();
[old] 638
[new] 810
..::[ WARNING 8-9 ]::..
warning C4244: 'argument' : conversion from 'int' to 'char', possible loss of data
Lines:
*tag += c;
[old] 653 and 669
[new] 825 and 841
..::[ WARNING 10-13 ]::..
warning C4244: 'argument' : conversion from 'int' to 'char', possible loss of data
Lines:
(*tag) += c;
[old] 878, 930, 1049 and 1079
[new] 1060, 1112, 1231 and 1261
Thanks! Fixed.
The first two warnings, and possibly the last two, are indicative of a slightly inappropriate use of get(). In particular, the chance of the stream returning EOF is being ignored, and therefore the EOF character - if encountered - would get appended onto the data before the reading loop terminates. (Assuming there is a separate termination condition.)
A very good point on the EOF issue! Definately worth looking in to.
I checked the STL docs:
"bool good ( ) const; Check if stream is good for i/o operations. The function returns true if none of the stream's error flags are set."
I did a search on the "get" calls in the parser and looked for issues.
checks for good():
TiXmlBase::StreamTo
TiXmlBase::StreamWhiteSpace
TiXmlDocument::StreamIn
TiXmlUnknown::StreamIn
TiXmlComment::StreamIn
TiXmlText::StreamIn
TiXmlDeclaration::StreamIn
needed a fixup:
TiXmlElement::StreamIn
With the fix - and assuming I understand good() - I think it's in pretty good shape. Do you agree on good() protecting against the EOF?
lee
Bear in mind that 'The function returns true if none of the stream's error flags are set'. And the only thing that can set those flags is a failed I/O operation, which in these cases is going to be a get() I believe. I heard that this is the case in C and C++ for the sake of efficiency (no hidden peek() calls to check the next operation will work).
Easiest to show this with an example:
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
fstream file("test.txt");
while (file.good())
{
int c = file.get();
cout << "Read character with value: " << c << endl;
}
return 0;
}
Create test.txt, fill it with a word or two, then watch the output. Look for the -1 at the end.
Very good point. I'll change the parsing code to check for the eof().
lee