Hi All I mentioned this briefly during the previous release cycle, but we all had more pressing things to deal with. Dealing with errors is something we really need to get a hold on for PLPlot 6 and one of the big drivers for considering a major API change. However, I am certain that the reason why this has been a problem s that propagating those errors back up through many layers of function calls is tedious and error prone so it has been much simpler to simply call exit().
Here is one possible solution. We switch the core code to C++ with a C frontend. I am aware some people on this list know C++ better than others, however, the actual code changes I am suggesting are relatively small. It may seem daunting, but I am not considering rewriting everything in an object oriented way, I am simply advocating using two features of C++ which will make our lives massively easier. I feel the change would be less painful that the switch from svn to git, but with much larger gains so please hear me out. So the following is aimed at those of us who are a bit wary of C++ that have better C skills. If I'm teaching my granny to suck eggs then I apologise. The first feature is throw-catch. It would work like this #define PLERR int #define PLERR_NONE 0 #define PLERR_OUTOFMEM 1 void someFunc(); PLERR plapiFunc( /*some parameters*/ ) { try { //Any number of function calls declarations etc down to any level //But for example lets call someFunc() someFunc(); } catch( PLERR err ) { return err; } } void someFunc() { PLINT *array=malloc( 100000000000000 *sizeof(PLINT); if( array == NULL ) throw( PLERR_OUTOFMEM ); //do some stuff free( array ); } So the way this works is that if at any time you call throw, the function returns to its calling function taking the parameter with it. If the call was made outside of a try block then it returns again and again until eventually it finds the try block and enters the catch block. In this case it assigns the error and returns it. Then execution continues from that point. This would mean that we could simply replace all exit calls with throw calls instead and the job would be done!!! Well actually that's not quite true. There is one other thing to deal with. Although we now don't exit, if any memory was allocated between the call in the try block and the throw then it will leak. This is still an improvement. Memory leaks are surely better than unexpected exits. At least now the user has the option to do something like write recovery data to disk and restart or try to trace the problem. But there is a solution. We create an array class. and do our memory allocations in that class. Here we are not talking about anything too fancy, just a simple class without any inheritance or polymorphism. It would look something like: class PLINTArr { public: PLINTArr(PLINT n); ~PLINTArr(); PLINT &operator[]( PLINT idx ); private: PLINT m_*mem; }; PLINTArr::PLINTArr( PLINT n ) { m_mem = malloc( n ); if ( !m_mem ) throw( PLERR_OUTOFMEM ); } PLINTArr::~PLINTArr() { free( m_mem ); } PLINTArr::PLINT &operator[]( PLINT idx ) { return m_mem[idx]; } How does this help? The joy of an object is that when you create one the constructor is called and when it goes out of scope the destructor is called. So we can now have void someFunc() { PLINTArr arr( 100000000000000 ); } This calls the constructor PLINTArr::PLINTArr with the number of elements we want in our array. Checking if the allocation was okay has been done for us so that saved us a job. And when arr goes out of scope PLINTArr::~PLINTArr is called and everything gets cleaned up, so we don't even have to worry about that either. But what is even better, we can do something like this void someFunc() { PLINTArr arr( 100 ); char *filename = getFilename(); if (strlen( filename ) == 0 ) throw( PLERR_FILENOTFOUND ); } If throw gets called then someFunc returns, arr goes out of scope, the destructor is called which cleans up for us and now we have perfect error reporting and no memory leaks!!! The effort required to make these changes is tiny compared to trying to propagate errors back through the code and track down memory leaks on the way. So it would be something that I would really like to push if people are open to it. Any thoughts? Phil ------------------------------------------------------------------------------ One dashboard for servers and applications across Physical-Virtual-Cloud Widest out-of-the-box monitoring support with 50+ applications Performance metrics, stats and reports that give you Actionable Insights Deep dive visibility with transaction tracing using APM Insight. http://ad.doubleclick.net/ddm/clk/290420510;117567292;y _______________________________________________ Plplot-devel mailing list Plplot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/plplot-devel