Portál AbcLinuxu, 5. května 2025 21:30

Dotaz: Chycení výjimky v C

29.12.2015 20:41 Jardík
Chycení výjimky v C
Přečteno: 664×
Odpovědět | Admin
Zahrávám si s myšlenkou chytit např. C++ výjimku v C kódu. Chápu, že to nebude přenositelné. Četl jsem nějakou dokumentaci k libunwind a našel způsob, jak z C vyhodím výjimku (musím linkovat k libgcc nebo k libunwind). Taky má GCC attribut cleanup, který mi zavolá funkci, když nějaká C++ funkce (callback) vyhodí výjimku, taže bych uměl i uklidit. Mou z C vyhozenou výjimku (pomocí _Unwind_RaiseException) dokáže chytit C++ catch(...) blok. Zajímalo by mě ale, jestli jde nějak kompilátoru (GCC) říct, aby zavolal nějakou funkci či skočil na návěští, když callback vyhodí výjimku. Prostě jen tak ze zvědavosti. Zahrávám si s myšlenkou v blízké budoucnosti vytvořit překladač nespecifikovaného jazyka do C a chtěl bych tam mít i výjimky, aniž bych použil C++, ale chtěl bych, aby to volalo i C++ destruktory a dalo se to chytit v catch(...) bloku, zavolá-li mou funkci někdo z C++.
// throwing_code.c

#include <stdint.h>
#include <stdio.h>

typedef enum {
	_URC_NO_REASON = 0,
	_URC_FOREIGN_EXCEPTION_CAUGHT = 1,
	_URC_FATAL_PHASE2_ERROR = 2,
	_URC_FATAL_PHASE1_ERROR = 3,
	_URC_NORMAL_STOP = 4,
	_URC_END_OF_STACK = 5,
	_URC_HANDLER_FOUND = 6,
	_URC_INSTALL_CONTEXT = 7,
	_URC_CONTINUE_UNWIND = 8
    } _Unwind_Reason_Code;
    
typedef struct _Unwind_Exception _Unwind_Exception;

typedef void (*_Unwind_Exception_Cleanup_Fn)
		(_Unwind_Reason_Code reason, _Unwind_Exception *exc);

struct _Unwind_Exception {
	    uint64_t			 exception_class;
	    _Unwind_Exception_Cleanup_Fn exception_cleanup;
	    uint64_t			 private_1;
	    uint64_t			 private_2;
    };


extern _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *e);


void exception_cleanup(_Unwind_Reason_Code reason, _Unwind_Exception *e)
{
	printf("Exception cleanup, reason = %i, e = %p\n", (int)reason, (void*)e);
}


_Unwind_Exception e = {
	((uint64_t)('J') << 56) | ((uint64_t)('A') << 48) | ((uint64_t)('R') << 40) |
	((uint64_t)('D') << 32) | ((uint64_t)('I') << 24) | ((uint64_t)('K') << 16) |
	((uint64_t)('\0') << 8) | ((uint64_t)('\0') << 0),
	exception_cleanup,
	0,
	0
};

void throwing_code_throw()
{
	_Unwind_RaiseException(&e);
}
// catching_code.cpp

#include <cstdio>

extern "C" void throwing_code_throw();

int main(int argc, char **argv)
{
	try {
		throwing_code_throw();
		printf("after exception\n");
	}
	catch (...) {
		printf("caught exception\n");
	}
	return 0;
}
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

kozzi avatar 30.12.2015 17:53 kozzi | skóre: 55 | blog: vse_o_vsem | Pacman (Bratrušov)
Rozbalit Rozbalit vše Re: Chycení výjimky v C
Odpovědět | | Sbalit | Link | Blokovat | Admin

Zrovna na toto tema se nedavno vedla diskuze u jazyka D. A pokud vim tak se uz i nekam pokrocilo a v blizko dobe bude mozne v D chytat vyjimky z C++. Takze mozna se poptat nekoho z fora D.

nejaka prace uz je i zaclenena ale nevim zda ti to bude uzitecne

https://github.com/D-Programming-Language/dmd/pulls?utf8=✓&q=is%3Apr+author%3AWalterBright+

Linux je jako mušketýři "jeden za všechny, všichni za jednoho"
31.12.2015 02:18 Jardík
Rozbalit Rozbalit vše Re: Chycení výjimky v C
Kouknu na to, díky.
DaBler avatar 31.12.2015 09:26 DaBler | skóre: 17 | blog: dabler | Brno
Rozbalit Rozbalit vše Re: Chycení výjimky v C
Odpovědět | | Sbalit | Link | Blokovat | Admin
Co použít std::set_unexpected a std::set_terminate? Viz http://stackoverflow.com/questions/4448677/can-a-c-program-handle-c-exceptions.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.