Exceptions werden nicht gefangen
-
Hallo,
ich habe in etwa folgenden C++ Code
try{ Klasse1 klasse; try{ klasse.funktion() } catch(std::exception e){ // gib error aus } } catch(std::exception e){ // gib error aus }Wenn ich das innere catch weg lasse, fängt der äußere catch Block meine Exception nicht, obwohl diese Typgleich sind. Der innere jedoch fängt diese korrekt. Einziger Unterschied: in der äußeren steckt halt noch der Konstruktor mit drin, aber der wirft selbst keine Exception (schon getestet).
Woran könnte's liegen?
-
Bitte sehr, gern geschehen. Jetzt kann man es entziffern. "Wo sind wir denn gewesen ..."
try { Klasse1 klasse; try { klasse.funktion() } catch(std::exception e) { // gib error aus } } catch(std::exception e) { // gib error aus }
-
Entziffern konnte man es auch vorher.
Allerdings zwei andere Dinge:
1. Ein ausführbares Minimalbeispiel wäre hier sehr hilfreich. Kann unter Umständen sogar dir helfen, den Fehler zu finden.
2. Man fängt eigentlich Referenzen und nicht Kopien.Grüssli
-
Danke für deine Antwort, das mit den Referenzen wusst ich noch nicht. Werd ich beachten.
Das mit dem ausführbaren Minibeispiel ist nicht so einfach, da die Klasse relativ komplex ist:
#include <exception> #include <iostream> class testMe{ public: testMe(); void funktion(){ throw std::exception; } }; int main(int argc, char** argv){ try{ testMe tester; try{ tester.funktion(); } catch(std::exception &e){ std::cerr << "Exception gefangen" << std::endl; } } catch(std::exception &f){ std::cout << "Exception gefangen" << std::endl; } }Das wäre es denke ich minimal, um zu verstehen was intern abgeht. Zu Testzwecken habe ich meiner wirklichen Funktion wirklich ein derartiges throw an die erste Zeile gestellt, es hängt also nicht vom Inhalt der Funktion ab.
Wenn ich das gleiche (throw an die erste Zeile) allerdings innerhalb des Konstruktors selbst mache, funktioniert es (der äußere Block fängt die Exception). Hilft dir das?
-
Wenn man die Syntaxfehler in deinem Beispiel korrigiert, dann funktioniert das einwandfrei. Gib uns bitte wirklich mal 1:1 ein Minimalbeispiel von dem, was bei dir nicht funktioniert.
-
main.cpp
extern "C"{ #include <libavformat/avformat.h> } #include "types.h" #include <iostream> #include <cstdlib> #include <stdexcept> #include "openCLProgram.h" using namespace GRAVID; int main(int argc, char** argv){ try{ OpenCLProgram tester; try{ tester.loadProgram("src/opencl/kernels/colorFilters.cl","grayFilter"); } catch(std::logic_error e){ std::cerr << e.what() << std::endl; } } catch(std::logic_error e){ std::cerr << e.what() << std::endl; exit(-1); }OpenCLProgram.h
#ifndef OPENCLPROGRAM_H_ #define OPENCLPROGRAM_H_ #include <CL/cl.h> #include <stdexcept> #include <string> #include "types.h" namespace GRAVID{ class OpenCLProgram{ private: // for opencl return codes cl_int errorCode; // the number of OpenCL capable platforms cl_uint nb_platforms; // the available platform ids cl_platform_id *pPlatformIDs; // the number of devices for the first platform cl_uint nb_devices; // the ids of the devices available for the first platform cl_device_id *pDeviceIDs; // the OpenCL context cl_context clCtx; // the current cl-program cl_program clProgram; // the loaded kernel within the loaded source cl_kernel clKernel; // the command queue for that kernel cl_command_queue cmdQ; void errorHappened(const char* error); std::string readKernel(const char* filename); public: OpenCLProgram(); ~OpenCLProgram(); void loadProgram(const char* filename, const char* kernelName); } #endif /* OPENCLPROGRAM_H_ */OpenCLProgram.cpp
#include "openCLProgram.h" #include "types.h" #include <CL/cl.h> #include <stdexcept> #include <string> #include <fstream> #include <iostream> using namespace GRAVID; OpenCLProgram::OpenCLProgram(){ // retrieve platform ids this->pPlatformIDs = NULL; clGetPlatformIDs(NULL,NULL,&(this->nb_platforms)); // stop, if there is no OpenCL platform if(0 == this->nb_platforms) this->errorHappened("no OpenCL capable platforms available"); this->pPlatformIDs = new cl_platform_id[this->nb_platforms]; // some memory is allocated that has to be freed in the destructor this->errorCode = clGetPlatformIDs(this->nb_platforms,this->pPlatformIDs,NULL); if(CL_SUCCESS != this->errorCode) this->errorHappened("couldn't get the platform ids"); // obtain the list of GPUs for the first platform this->pDeviceIDs = NULL; clGetDeviceIDs(this->pPlatformIDs[0],CL_DEVICE_TYPE_GPU, NULL, NULL, &this->nb_devices); // stop, if there is no device available if(0 == this->nb_devices) this->errorHappened("no device available for the first platform"); this->pDeviceIDs = new cl_device_id[this->nb_devices]; this->errorCode = clGetDeviceIDs(this->pPlatformIDs[0],CL_DEVICE_TYPE_GPU, this->nb_devices, this->pDeviceIDs, NULL); if(CL_SUCCESS != this->errorCode) this->errorHappened("couldn't get the device ids"); // create a context for the devices to use cl_context_properties clContProperties[3]; clContProperties[0] = CL_CONTEXT_PLATFORM; clContProperties[1] = (cl_context_properties)this->pPlatformIDs[0]; clContProperties[2] = 0; this->clCtx = clCreateContext(clContProperties,this->nb_devices,this->pDeviceIDs,NULL,NULL,&this->errorCode); if(CL_SUCCESS != this->errorCode) this->errorHappened("couldn't create context"); } void OpenCLProgram::errorHappened(const char* error){ std::string errorMsg = error; throw std::logic_error(errorMsg); } OpenCLProgram::~OpenCLProgram(){ clReleaseCommandQueue(this->cmdQ); clReleaseKernel(this->clKernel); clReleaseProgram(this->clProgram); clReleaseContext(this->clCtx); if(NULL != this->pDeviceIDs) delete(this->pDeviceIDs); if(NULL != this->pPlatformIDs) delete(this->pPlatformIDs); } std::string OpenCLProgram::readKernel(const char* filename){ std::ifstream inFile; char buffer[256]; std::string resultString; inFile.open(filename,std::ifstream::in); if(inFile.fail()) this->errorHappened("kernel source-file not found"); while(inFile.good()){ inFile.getline(buffer,256); resultString.append(buffer); } inFile.close(); return resultString; } void OpenCLProgram::loadProgram(const char* filename, const char* kernelName){ // retrieve the kernel source std::string kernelString = this->readKernel(filename); const char* kernel_cstr = kernelString.c_str(); size_t kernelLength = (size_t)kernelString.length(); this->clProgram = clCreateProgramWithSource(this->clCtx, 1, &kernel_cstr, &kernelLength,&this->errorCode); if(CL_SUCCESS != this->errorCode) this->errorHappened("couldn't create program from source"); // build the program // TODO check if there maybe a built version already exists this->errorCode = clBuildProgram(this->clProgram,NULL,NULL,NULL,NULL,NULL); // get Build Information size_t actualSize; clGetProgramBuildInfo(this->clProgram,this->pDeviceIDs[0],CL_PROGRAM_BUILD_LOG,NULL,NULL,&actualSize); char errorMessage[actualSize]; clGetProgramBuildInfo(this->clProgram,this->pDeviceIDs[0],CL_PROGRAM_BUILD_LOG,actualSize,(void*)errorMessage,NULL); if(CL_SUCCESS != this->errorCode){ std::string totalError = "Building process failed with the following error log:\n"; totalError.append(errorMessage); this->errorHappened(totalError.c_str()); } // extract the kernel within the program this->clKernel = clCreateKernel(this->clProgram,kernelName,&this->errorCode); if(CL_SUCCESS != this->errorCode) this->errorHappened("couldn't extract the specified kernel from the loaded source"); // creating the commandQueue for the kernel this->cmdQ = clCreateCommandQueue(this->clCtx, this->pDeviceIDs[0], NULL, &this->errorCode); if(CL_SUCCESS != this->errorCode) this->errorHappened("couldn't create command queue"); }Sry, but I couldn't post less to make it work (or in this case not work).
-
Achja und sry dafür dass mir manchmal die Srachorientierung fehlt

-
keine angst - das mit der sprachorientierung wird niemanden stören - weil du offenbar nicht fähig bist ein _compilierbares minimalbeispiel_ zu posten...
bb