How do I write exception safty code?

D

dragon9

I want to write some small programs with exception safety, but I don't how
to write. Because my programs wrap C-api function( example: win32 api). I
don't find my direction. I wish any hot heart man to help me. My english is
too bad. I am sorry! Thanks!

#include "windows.h"
#include <string>
//
#ifndef FILE1_H
#define FILE1_H
namespace wukexin{
//
std::string Fileattrib_to_str( const DWORD attrib );
//
std::string Filetime_to_str( const FILETIME* x );
//
class Cfile_information
{
public:
explicit Cfile_information(std::string fname){initializer(fname);};
//~Cfile_information(){destroyer();};
void print();
protected:
//friend ostream& operator<< (std::eek:stream& os, const Cfile_information&
file);
private:
void initializer(std::string fname);
void destroyer();
bool destroySuccess_;
HANDLE hfile_;
std::string fname_;
WIN32_FIND_DATA file_;
};
}
#endif //file1.h
////////////////
file.cpp
//**
void Cfile_information::initializer(std::string fname){
WIN32_FIND_DATA file;
//std::cout<<fname<<"construct success!\n";
hfile_=FindFirstFile(fname.c_str(),&file_);
if(INVALID_HANDLE_VALUE == hfile_){
//std::cout<<"FindFirstFile(fname,&file) run error!\n"<<std::endl;
throw <<"FindFirstFile(fname,&file) run error!\n";
}
destroySuccess_=false;
}
//
Cfile_information::~Cfile_information(){
if( !destroySuccess_ ){
try{
destroyer();
}
catch(){
// codes
}
};
//**
 
A

asterisc

I want to write some small programs with exception safety, but I don't how
to write. Because my programs wrap C-api function( example: win32 api). I
don't find my direction. I wish any hot heart man to help me. My english is
too bad. I am sorry! Thanks!

#include "windows.h"
#include <string>
//
#ifndef FILE1_H
#define FILE1_H
namespace wukexin{
//
std::string Fileattrib_to_str( const DWORD attrib );
//
std::string Filetime_to_str( const FILETIME* x );
//
class Cfile_information
{
public:
explicit Cfile_information(std::string fname){initializer(fname);};
//~Cfile_information(){destroyer();};
void print();
protected:
//friend ostream& operator<< (std::eek:stream& os, const Cfile_information&
file);
private:
void initializer(std::string fname);
void destroyer();
bool destroySuccess_;
HANDLE hfile_;
std::string fname_;
WIN32_FIND_DATA file_;
};}

#endif //file1.h
////////////////
file.cpp
//**
void Cfile_information::initializer(std::string fname){
WIN32_FIND_DATA file;
//std::cout<<fname<<"construct success!\n";
hfile_=FindFirstFile(fname.c_str(),&file_);
if(INVALID_HANDLE_VALUE == hfile_){
//std::cout<<"FindFirstFile(fname,&file) run error!\n"<<std::endl;
throw <<"FindFirstFile(fname,&file) run error!\n";
}
destroySuccess_=false;
}
//
Cfile_information::~Cfile_information(){
if( !destroySuccess_ ){
try{
destroyer();
}
catch(){
// codes
}
};
//**

Firstly, it's not a good practice to send non-pointer non-reference
types by const, because a copy it will be used anyway.
Another idea is to return an error code from the function and pass
through references your data, for example:
std::string Fileattrib_to_str( const DWORD attrib );

bool Fileattrib_to_str( DWORD attrib, std::string& retVal );

Exceptions should be used in exceptional cases only, everything else
should be treated as errors.
Exception mechanism is very slow as well.

I think you should refactor your code.

Use it carefully!
 
A

AnonMail2005

I want to write some small programs with exception safety, but I don't how
to write. Because my programs wrap C-api function( example: win32 api). I
don't find my direction. I wish any hot heart man to help me. My english is
too bad. I am sorry! Thanks!

#include "windows.h"
#include <string>
//
#ifndef FILE1_H
#define FILE1_H
namespace wukexin{
//
std::string Fileattrib_to_str( const DWORD attrib );
//
std::string Filetime_to_str( const FILETIME* x );
//
class Cfile_information
{
public:
explicit Cfile_information(std::string fname){initializer(fname);};
//~Cfile_information(){destroyer();};
void print();
protected:
//friend ostream& operator<< (std::eek:stream& os, const Cfile_information&
file);
private:
void initializer(std::string fname);
void destroyer();
bool destroySuccess_;
HANDLE hfile_;
std::string fname_;
WIN32_FIND_DATA file_;
};}

#endif //file1.h
////////////////
file.cpp
//**
void Cfile_information::initializer(std::string fname){
WIN32_FIND_DATA file;
//std::cout<<fname<<"construct success!\n";
hfile_=FindFirstFile(fname.c_str(),&file_);
if(INVALID_HANDLE_VALUE == hfile_){
//std::cout<<"FindFirstFile(fname,&file) run error!\n"<<std::endl;
throw <<"FindFirstFile(fname,&file) run error!\n";
}
destroySuccess_=false;
}
//
Cfile_information::~Cfile_information(){
if( !destroySuccess_ ){
try{
destroyer();
}
catch(){
// codes
}
};
//**

Read Sutter's Exceptional C++. In it, there's a series of examples
that
systematically walks the reader through the implementation of a stack
container and teaches the fundamentals of exception safety along the
way.

A must read for any serious C++ programmer IMHO.
 
D

dragon9

Thanks very much, my question is how to wrap C-api functions with exception
safety.
example:
FindFirstFile(),etc.
 
B

BobR

dragon9 said:
Thanks very much, my question is how to wrap C-api functions with exception
safety.
example:
FindFirstFile(),etc.

FindFirstFile() is windows, so, your best bet on that is to try a windows
NG. This group is for C++ (standard) language.


#include <iostream>
#include <exception>
#include <stdexcept>

class MyError : public std::runtime_error { public:
MyError( std::string const &msg = "") : std::runtime_error(msg){}
};

void SomeFunc(){
// you find an error that you can not recover from here, so you do:
throw MyError( "Rats, I really hate when that happens!!");
return; // it won't get here
}

int main() try {

// - your code here -

SomeFunc(); // for test

std::cout<< "main() finished"<<std::endl;
return 0;
} // main()

catch( MyError const &Me ){
std::cout<< "main() caught MyError: "
<<Me.what()<<std::endl;
return 1;
}
catch( std::exception const &Se) {
std::cout<< "main() caught exception: "
<<Se.what()<<std::endl;
return 1;
}
catch( ... ) {
std::cout<<"caught unknown"<<std::endl;
return 1;
}


See "Thinking in C++" vol.2
"Part 1: Building Stable Systems, 1: Exception Handling.

Get "Thinking in C++", 2nd ed. Volume 1&2 by Bruce Eckel
(available for free here. You can buy it in hardcopy too.):
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html


FAQ http://www.parashift.com/c++-faq-lite
 
J

James Kanze

Thanks very much, my question is how to wrap C-api functions with exception
safety.
example:
FindFirstFile(),etc.

If it's a function from a C API, you don't need to do anything
with regards to exception safety, since the function will never
throw. Otherwise, it couldn't be used from C. In particular,
both the Windows API and Posix are C, and none of the functions
in these API's ever raise an exception. (I think. I'm 100%
sure about Posix, but I think Windows is the same.)

If you want the function to throw for certain types of errors,
you'll have to wrap it, check the return status, and manually
throw the exception you want for the types of errors you want.
Regardless of whether you want to throw or not, I would strongly
recommend wrapping all of the system API in some sort of
platform neutral C++ interface; I use something roughly similar
to java.io.File, for example, with different implementations for
Windows and for Posix/Linux. And some of the functions in this
class do throw, for certain types of errors.
 
D

dragon9

Thank everyone. Now I haven't any good done, but I simple use
std::runtime_error to wrap it.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Thank everyone. Now I haven't any good done, but I simple use
std::runtime_error to wrap it.

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Please, do not use other peoples signatures, it really confuses people.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top