Newsgroup: it.comp.lang.c
Titolo: Personalizzazione di -ftrapv in gcc

Ciao.
Avrei bisogno di un po' di aiuto nell'uso dell'opzione di compilazione
-ftrapv.
Da manuale, questa opzione sostituisce le routine assemply, relative
ad operazioni algebriche, a routine poste in libc che verificano
quando accade overflow.
Nel funzionamento standard, quando accade overflow a video appare la
scritta Aborted ed il programma termina.
La mia domanda e' la seguente. si potrebbe sostituire questo
comportamento in modo da, per esempio ottenere una scritta a video ma
restituire il controllo al programma chiamante.
In altre parole e' possibile gestirsi l'overflow artimetico su interi?
Grazie
Daniele


Yes - basta gestire il segnale SIGABRT


Per cortesia potresti indicarmi un riferimento in cui trovare un
esempio di tale gestione?
Avevo trovato qualcosa relativa agli handler ma non sono riuscito ad
ottenere un esempio abbastanza chiaro.
Gazie

 Gazie
Anche se non è relativo al C, ti posto comunque due righe di esempio -
per informazioni più dettagliate magari trovi più informazioni su
gruppi su gcc o su unix
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <signal.h>
__sighandler_t sig_oldabort;
void mysignal(int i) {
    printf("Received signal %d\n", i);
}
int main(void) {
    int a, b;
    sig_oldabort = signal(SIGABRT, ciao);
    a = INT_MAX;
    b = a+a;
    printf("%d\n", b);
    signal(SIGABRT, sig_oldabort);
    return 0;
}


Prima di tutto grazie.
Ho provato a compilare le righe che mi hai inviato ma ottengo questi
errori (i codice si chiama abrt_custm.c):
abrt_custm.c:6: error: parse error before "sig_oldabort"
abrt_custm.c:6: warning: data definition has no type or storage class
abrt_custm.c: In function `main':
abrt_custm.c:15: error: `ciao' undeclared (first use in this function)
abrt_custm.c:15: error: (Each undeclared identifier is reported only
once
abrt_custm.c:15: error: for each function it appears in.)
abrt_custm.c:15: warning: assignment makes integer from pointer
without a cast
abrt_custm.c:19: warning: passing arg 2 of `signal' makes pointer from
integer without a cast
mi puoi ancora aiutare ?
grazie in ogni caso


:D sorry, ho scritto due nomi di funzioni diverse :)  ovviamente al
posto di "ciao" andava "mysignal" (ovvero il secondo parametro della
funzione signal() è un puntatore all funzione di callback. Questo
dovrebbe risolvere tutti i problemi alla riga 15 :D sono un po'
sbadato ultimamente.
Per quanto riguarda il tipo "sighandler_t" cerca nella documentazione
del tuo sistema. Tipicamente è "sighandler_t", ma anche
"__sighandler_t" a volte è disponibile. Comunque è semplicemente un
puntatore a funzione che prende come parametro un int e ritorna void,
quindi void(*sighandler_t)(int)


Devo scusarmi anche io perche' il codice l'avevo provato su cygwin in
cui il gcc e' una versione vecchia e quindi l'opzione -ftrapv non
funziona o funziona male.
Riprovando in linux gcc versione 4.1.2  e sostituendo ciao con
mysignal, riesco a compilare senza ottenere errori pero'
se inserisco l'opzione -ftrapv l'uscita  e':
Receiver signal 6
Aborted
senza l'opzione -ftrapv l'uscita e'
-2
Invece quello che io vorrei sarebbe qualcosa del genere:
Overflow
-2
ciao


Sopra sono sempre io che ho fatto confusione con due indirizzi gmail :-
(


Ciao
Buona domanda, non so come e se sia possibile fare una cosa del genere
- o meglio, di certo si, ma su due piedi non riesco a trovare una
soluzione facile. Ti consiglio (almeno per capire bene quello che
succede al di sotto del codice che scrivi) di usare lo "strace" che ti
da utili informazioni delle chiamate di sistema che effettua il
programma. Se mi vengono in mente soluzioni ti faccio sapere! Comunque
io taglierei la testa al toro e chiederei su comp.unix.programming


Grazie del feedback.
Ho provato a postare la domanda su gnu.gcc.help ma al momento che ti
rispondo, non ho avuto risposta.
Pensandoci con altri colleghi, pensavamo di aver risolto il problema
tramite una fork e la cosa funzionerebbe bene se la fork fosse
eseguita
nel main. Purtroppo, il programma che necessita questa verifica
sull'overflow, e' una minima parte di un sistema piu' complesso che,
sia pur al 90%, con o senza overflow lavorerebbe comunque bene.
Fare la fork nel main e' impensabile e quindi mi ritrovo al punto di
prima.
Al momento l'overflow lo verifico facendo praticamente il doppio delle
operazoni con un'inefficienza pazzesca.
L'idea bella del signal era che proaticamnte il controllo viene
effettuato dal sistema operativo e, riuscissi a gestire la cosa, alla
fiene del processo basterebbe
per esempio testare il valore di una variabile per verificare se c'e'
stato overflow oppure no ed eventualmente, 
p.es
. rilanciare la
procedura.
Avevo anche immaginato per esempio di testare lo Status Register del
processore che dovremmo usare (per esempio utilizzando istruzioni del
tipo asm) ma anche quella strada non ha dato buoni esiti
Adesso potrei provare a copiare la domanda fatta su gcc help su
comp.unix e speriamo bene
Ciao e grazie


Anche se magari è semplicistico, se i punti dove il codice può dare
overflow son pochi potresti anche usare dei "trucchetti" (riporto
l'esempio di sopra ma la generalizzazione è banale)
if ((b=a+a)<a) { overflow(); }
ovviamente tenendo conto di segni e vari operazioni.
Al contrario se è molto probabile che l'overflow avvenga credo sia
meglio ristrutturare il codice per dei tipi più grandi.
Ciao!


Piu' o meno e' esattamente quello che gia faccio e se nella somma te
la cavi con l'aggiunta di un confronto, nella moltiplicazione devo
fare una divisione preventiva per essere sicura di non andare in
overflow. I tipi sono credo il massimo (long long int = 64 bit) ma
cio' nonostante ci sono casi in cui he verificato l'overflow (facendo
i conti a mano per intenderci).
Ciao


Ho posto la domanda anche su comp.unix.programmer
ma sto remando alla grande.
Ho gia' provato con setjmp/longjmp ma sono caduto in un baco
riconosciuto di queste funzioni.
Come puoi leggere, mi hanno anche suggerito l'uso di shared memory che
mi accingo a provare
Ciao

 Ciao
Ma, tanto per curiosità, cosa deve fare questo programma? Non riesco
proprio ad immaginare una situazione in cui ti arrivano input così
grandi, dei quali "il 90% delle volte" possono andare in overflow, e
che per giunta deve essere ottimizzato su tali operazioni.


Semplice: immagina di fare una FFT in fix point su potenze di due
abbastanza grandi.....
.....devi moltiplicare tra di loro i numeri un numero di volte pari
alla potenza adi due.
Pur facendo gli opportuni shift .......BOOM!
(ovviamente in campo complesso)


Alla fine ci sono riuscito per mezzo delle istruzioni setjmp/longjmp.
Grazie dei consigli e dei suggerimenti
Ciao
Daniele