[comp.lang.c++] Some Questions from a C++ beginner

thawk1@ibmpcug.UUCP (Timothy Hawkins) (03/07/89)

I have two questions that are bothering me at the moment and I wondered
if some kind person in netland could enlighten me.. 

The first concerns tempoary class instances ; consider the following

	'database' is a class that has a constructor that takes a
	database name and opens it. It also read the structure of 
	the record into the data area of the class instance. Its
	destructor closes the file and cleans up memory... It has 
	a member function called create that copys a record structure
	from a database reference passed to it and creates a new
	(un-nammed) database of the same structure..

	I wish to do the following:

	database xx;             // un-named database with no structure

	void	copy_dbf( char *name )
	{

		xx.create( database( "TEST" ) );

		.......... other statements ..........

	}

	My first question is; is the scope of " database( "TEST" ) " ( a 
	tempoary class created soley to obtain the structure of another
	database) the scope of the whole function "copy_dbf" or is its scope
	limited to the stage of constructing the stack frame for the 
	" xx.create( ... ); " call.. In the case of a class that uses files
	it is important that I know were the clean-up is done prior to executin
	further code in that function... If this is valid in the language.
	what is the status in the various implementations?. ( I am using
	Zortech C++ 1.05 and Glockenspiel Designer C++ Beta 2A , both on
	Msdos 3.2 ).. This question is simular in vein to the "for" loop
	counter variable question, that has been recently discussed..

Second Question... 

	I am trying to implement a generic error handler class

	ie: 

	class error_handler 
	{
		jmpbuf	error_point;
		int	error_defined;
	public:
	
	inline  error_handler( void )
	{
		error_defined = 0;
	}
	
	inline  virtual int error( void )
	{
		return( setjmp( error_point));	
	}

	inline  virtual void error( int error_code ) 
	{
		longjmp( error_point, error_code );
	}
	}

	The theory is that the handle could be inherited into complex 
	classes and allows the following.......

	{
		database xx;
		database yy;

		if( xx.error() || yy.error())
		{
			printf("Database Error\n");
			exit(0);
		}

	The member functions of the class could call error(n) to handle
	fatal errors..... 

	Can anybody think of any good reason for not using this scheme or
	has anybody got any experience with a mainstream C++ compiler that
	cannot handle this construction... I would appreaciate it as I am
	hoping to write some libarys that will be ported to various C++
	systems and I wish to minimise the compiler dependancys..... 

Thank you for all you forthcomming help 
	Tim hawkins  thawk1@ibmpcug 
	Tel 44 242 581145 .................

-- 
Automatic Disclaimer:
The views expressed above are those of the author alone and may not
represent the views of the IBM PC User Group.

jeenglis@nunki.usc.edu (Joe English) (03/10/89)

thawk1@ibmpcug.UUCP (Timothy Hawkins) writes:
[example using class 'database':]
>
>	database xx;             // un-named database with no structure
>
>	void	copy_dbf( char *name )
>	{
>
>		xx.create( database( "TEST" ) );
>
>		.......... other statements ..........
>
>	}
>
>	My first question is; is the scope of " database( "TEST" ) " ( a 
>	tempoary class created soley to obtain the structure of another
>	database) the scope of the whole function "copy_dbf" or is its scope
>	limited to the stage of constructing the stack frame for the 
>	" xx.create( ... ); " call.. 

database("TEST") creates a temporary object that is only guaranteed
to exist for the duration of the call to xx.create().  It will get
destroyed before the enclosing function (copy_dbf) exits; exactly *when*
this happens is not specified, though it typically (in Zortech at least)
will happen right after the function (xx.create) returns.

>Second Question... 
>
>	I am trying to implement a generic error handler class
>
[stuff deleted]
>
>	inline  virtual int error( void )
       [I think this is supposed to be error_handler::error(void) --J]
>	{
>		return( setjmp( error_point));	
>	}
>
[more stuff deleted]
>	Can anybody think of any good reason for not using this scheme 

I can:  This will break badly.  Since the function is virtual,
it will be called through a function pointer in the virtual
function table.  Which means that it won't get inlined.  Which
means that an actual function call is made, setjmp() does
its thing, then the *function returns*, rendering the error_point
jmpbuf totally invalid.

Even if you were to make it non-virtual, I still wouldn't do 
it.  Inline functions are supposed to have the exact same semantics
as real functions.   (I think of 'inline' the same way I think
of 'register,' as a hint to the compiler.  In some ways, this is
exactly the case because not all compilers will in fact inline all functions
that are supposed to be inlined --  Zortech for one.)

And thirdly, I wouldn't use setjmp() and longjmp() in a C++
program at all until the problems with exception handling get
worked out.  (What happens when you have a whole bunch of
local objects with non-trivial destructors that get skipped over
by the longjmp()?)  Unless your error handler is just going
to bail out and exit(), this is *not* a good idea.

--Joe English

  jeenglis@nunki.usc.edu