The problem.
See the below code... I was missing the return field;
statement and didn't spot it for a few debug runs. I would never have thought that something like that would get past the compiler without an error! Why did it?
Description
I have an parser object that uses std::tr1::function
to have receive a translation algorithm on construction. The translation converts from a string to an object of type TransportableMessage
, which is made of TMFields
, which can hold different types. So anyway I made a factory function for the creation of the fields because the type of the field is based on a string (from the XML), and while there is only a few now, it may be that there are more in the future.
The tstring
object is a typecast based on UNICODE
and basically resolves to std::wstring
at the minute. Also because I am using VS2008 unique_ptr
is not there so I have hidden std::auto_ptr
behind ScopedPtr_t
to make an upgrade easier and thus more likely to happen.
namespace arc
{
namespace util
{
int internalTest()
{
std::cout << "Any error?" << std::endl;
}
ScopedPtr_T<TMField> TmFieldFactory( const tstring& name, const tstring& typeName, const tstring& value )
{
ScopedPtr_T<TMField> field;
int a = internalTest();
if( typeName == _T("int") || typeName == _T("long") )
{
field.reset( new TMNumericField( name, boost::lexical_cast<__int64>(value) ) );
}
else if( typeName == _T("string") )
{
field.reset( new TMStringField( name, value ) );
}
else if( typeName == _T("timestamp") )
{
field.reset( new TMTimeField( name, boost::lexical_cast<__int64>(value) ) );
}
else
{
std::string info( __FILE__ " :: " __FUNCTION__ " : Unrecognized TmField type ");
std::string type( typeName.begin(), typeName.end() );
info += type;
throw ARC_Exception( info.c_str() );
}
return field; // I WAS MISSING THIS!
}
}
}
Basically I would like to know if anyone else has had problems with this? I introduced the function internalTest
to see if the problem was specific to scoped_ptr
s but it appears that it is not. I also tried using internalTest
in GCC and it returned an error.
Why did it Visual Studio not flag this? Am I missing a compilation setting somewhere that I can turn on? Does the standard allow this? Apologies if this is something well known, I did google and look for answers here.
EDIT:: Calling Code - Just adding this for more context.
SharedPtr_T<TransportableMessage> strToTmConvFunc_Default_Apc7_0(const std::string& tm_str)
{
pugi::xml_document xmlDoc;
if( false == xmlDoc.load( tm_str.c_str() ) )
{
ARC_LOG(LOG_WARN, "The passed TM object was malformed. %s", tm_str.c_str() );
throw ARC_Exception( "Malformed Transportable Message XML" );
}
pugi::xml_node tmBase = xmlDoc.first_child();
std::string xmlRootName( tmBase.name() );
if( xmlRootName.compare("TM") != 0 )
{
ARC_LOG(LOG_WARN, "The passed TM object was malformed. %s", tm_str.c_str() );
throw ARC_Exception( "Malformed Transportable Message XML" );
}
std::string tmname = tmBase.child("N").child_value();
std::string entity = tmBase.child("E").child_value();
ARC_LOG(LOG_INFO, "TM message received for parsing. TM name is %s", tmname.c_str() );
tstring t_tmname( tmname.begin(), tmname.end() );
SharedPtr_T<TransportableMessage> tm_obj( new TransportableMessage( t_tmname, 0 ) );
pugi::xml_node fields = tmBase.child("FS");
for( pugi::xml_node field = fields.first_child(); field; field = field.next_sibling("field") )
{
tm_obj->addField( arc::util::TmFieldFactory( field.child_value("N"), field.child_value("T"), field.child_value("V") ) );
}
return tm_obj;
}