🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #307943

Jak są zaimplementowane wyjątki ?

#307943
From: Borneq
Date: Fri, 11 Dec 2015 07:44
91 lines
3174 bytes
Kiedyś na tej grupie (w 2012 roku) był przykład z C implementującymi 
wyjątki za pomocą setjmp/longjmp:
#include <setjmp.h>
#define finally else

/* Typy wyjątków */

#define DivisionByZero 1
#define MemoryAllocError 2
jmp_buf ex_buffer;
int ex_status;
#include <stdio.h>

int calc(int w)
{
          if(w%2)
          {
                  return 0;
          } else
          {
                  longjmp(ex_buffer, DivisionByZero);
          }
}

int main(int argc, char* argv[])
{
          int w = 2;
          if ((ex_status = setjmp(ex_buffer)) == 0)
          {
                  printf("Zwrócono %d\n", calc(w));
          } else if (ex_status == DivisionByZero)
          {
                  printf("Chwycono wyjątek\n");
          }
          return 0;
}

Ograniczeniem jest to, że chwyta tylko wysłane wyjątki, a nie wyjątki 
maszynowe jak błąd dzielenia czy pamięci.
A jak gcc sobie radzi?
int main (void)
{
   int n=5;
   int d=0;
   int g;
   try
   {
     g = n/d;
     throw "";
   }
   catch(...)
   {
   g=0;
   }
   return 0;
}
generuje :
.LC0:
         .string ""
main:
         push    rbp
         mov     rbp, rsp
         sub     rsp, 16
         mov     DWORD PTR [rbp-4], 5
         mov     DWORD PTR [rbp-8], 0
         mov     eax, DWORD PTR [rbp-4]
         cdq
         idiv    DWORD PTR [rbp-8]
         mov     DWORD PTR [rbp-12], eax
         mov     edi, 8
         call    __cxa_allocate_exception
         mov     QWORD PTR [rax], OFFSET FLAT:.LC0
         mov     edx, 0
         mov     esi, OFFSET FLAT:typeinfo for char const*
         mov     rdi, rax
         call    __cxa_throw
         mov     rdi, rax
         call    __cxa_begin_catch
         mov     DWORD PTR [rbp-12], 0
         call    __cxa_end_catch
         mov     eax, 0
         leave
         ret

Link do gcc.godbolt.org: https://goo.gl/0J8TUn
Tu po prostu zamiast skoków używa wywołań funkcji 
__cxa_allocate_exception,__cxa_throw,__cxa_begin_catch,__cxa_end_catch
Trzeba by się przypatrzyć ich wnętrzu.
Ale uwaga - gdy w .c nie było throw, wtedy nie ma obsługi wyjątku mimo 
dzielenia. Czyżby gcc nie potrafił obsługiwać tego typu wyjątków? Co się 
stanie, gdy jednak będzie błąd dzielenia?
Technical Details
Message-ID: <n4durn$q3e$1@node1.news.atman.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!.POSTED!not-for-mail

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!.POSTED!not-for-mail
From: Borneq <borneq@antyspam.hidden.pl>
Newsgroups: pl.comp.lang.c
Subject: Jak są zaimplementowane wyjątki ?
Date: Fri, 11 Dec 2015 08:44:16 +0100
Organization: ATMAN - ATM S.A.
Lines: 91
Message-ID: <n4durn$q3e$1@node1.news.atman.pl>
NNTP-Posting-Host: 91.239.205.105
Mime-Version: 1.0
X-Trace: node1.news.atman.pl 1449819831 26734 91.239.205.105 (11 Dec 2015 07:43:51 GMT)
X-Complaints-To: usenet@atman.pl
NNTP-Posting-Date: Fri, 11 Dec 2015 07:43:51 +0000 (UTC)
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0
X-Mozilla-News-Host: news://news.atman.pl:119
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit