Newsgroup: it.comp.lang.c
Titolo: Switch, goto e label

Esiste un modo elegante (quindi senza asm in linea) per ottenere uno 
switch/case senza confronti?
Praticamente si tratterebbe di usare array di puntatori non a funzioni, 
ma a label.
Kiuhnm

Kiuhnm wrote:

E me lo chiami "elegante"? E poi a che pro?

 ma a label.
Non con il C standard. Il gcc supporta un'estensione che fa quello che
chiedi:
void *lut[10] = {&&label1, &&label2, &&label3, ecc};
int x;
goto *lut[x];
label1:
...
label2:
...
label3:
...
Per i dettagli:
info gcc "C Extensions" "Labels as Values"
Luca
-- 
Home: 
http://kronoz.cjb.net
Windows NT: Designed for the Internet. The Internet: Designed for Unix.


Lo standard non obbliga ad avere una determinata implementazione 
(naturalmente!).
In genere conviene lasciare la scelta dell'  implementazione al 
compilatore. La probabilita'  che la versione "fatta in casa sia meno 
efficiente di quella fornita dal compilatore e'  altissima".
Tieni presente che spesso i compilatori "scelgono" come implementare lo 
switch-case in funzione del numero di casi e della sparsita'  dei valori.
P.es. gcc implementa uno switch-case a 2 vie come confronti ma se 
aggiungi abbastanza casi contigui, ad un certo punto il compilatore 
sceglie di usare una jump table.
In ogni caso,  non mi preoccuperei del problema a meno di non aver 
verificato sperimentalmente che lo switch e'  la parte critica del tuo 
programma (e finora non ho mai visto un caso del genere !).
Giorgio

 programma (e finora non ho mai visto un caso del genere !).
Ho realizzato un disassembler in asm basato esclusivamente su tavole. E' 
veramente veloce e avevo pensato di convertirlo in C, ma forse è meglio 
lasciarlo in asm, a 'sto punto.
In C potrei usare ptr a funzioni, ma diventerebbe tutto molto più lento, 
infatti in asm uso varie label disposte in modo da minimizzare i jmp 
necessari (è come una pipeline nella quale entri però a diverse altezze).
Comunque ho chiesto perché non si sa mai...
Kiuhnm

 lasciarlo in asm, a 'sto punto.
Scusa l'ignoranza,
ma quanto e' critica la velocita' di un disassembler ?
Non mi e' chiaro se l'utente potrebbe discriminare tra
la velocita' di un disassembler scritto in C e uno scritto in asm.
(Forse non mi e' chiaro esattamente cosa deve fare il disassembler).
ciao,
g.

 credo proprio che sia molto meno efficiente di uno scritto in assembler.
Il compilatore, ogni volta che cerca di ottimizzare codice, affronta un 
problema NP-Hard. Il programmatore può avere maggior successo 
nell'ottimizzare *particolari* parti di codice sfruttando informazioni 
che non possono essere fornite al compilatore e che spostano il problema 
in P.
Kiuhnm

 ma quanto e' critica la velocita' di un disassembler ?
Quando una funzionalità viene resa disponibile tramite un "modulo" 
allora la velocità è critica.
In uno strumento di analisi del codice, potrebbe essere necessario 
disassemblare anche GB di codice eseguito nelle ultime n ore.
La questione è questa:
se realizzi una funzione che ha il formato
I->A->B->C->O
dove I e O sono risp. input e output, allora non è necessario 
ottimizzare le parti che influiscono di poco sul tempo totale, ma se 
s'implementano le singole parti A, B e C separatamente e le si rendono 
disponibili come funzioni utilizzabili in qualsiasi contesto, allora 
vanno ottimizzate tutte.
Kiuhnm

 Kiuhnm
Non metto in dubbio la cosa ma dopo 20 anni di esperienze mi fido piu` 
delle ottimizzazioni fatte da un buon compilatore che non di quello che 
scrive un programmatore in assembler.
O stai facendo esercizi per imparare l'assembler o stai perdendo tempo.
E poi quanto sono importanti le dimensioni e la velocita` in un 
programma del genere?  Non credo tu stia portandolo su di un micro 
controllore.
IMO la mantenibilita` di un programma scritto in C lo rende superiore a 
qualsiasi programma in assembler anche se quest'ultimo e` piu` piccolo e 
piu` veloce.


 O stai facendo esercizi per imparare l'assembler o stai perdendo tempo.
Detto da un esperto come te che ha passato la vita a fare emulatori, 
strumenti per il debugging, decompilatori e simili deve essere vero per 
forza.
Ok, mi fido.
Kiuhnm


Chiaramente il compilatore non puo' fare miracoli.
Pero' da quello che ho visto, confrontando un listato in C con la 
versione tradotta in assembler, direi che a volte il compilatore fa 
delle "furbate" notevoli.
E' vero che in casi particolari l'umano potrebbe trovare
qualcosa di meglio, ma se quel qualcosa e' molto diverso dalla
versione trovata dal compilatore, allora vale la pena chiedersi
se il problema sia nel compilatore o in una versione iniziale
in C migliorabile.
Viceversa, nella stragrande maggioranza dei casi, un compilatore
puo' impiegare tutta una batteria di "trucchetti" e ottimizzare
ad esempio l'uso dei registri, fare cose che magari non sono alla
portata dell'umano "medio" e arrivare ad un codice assembler che sembra 
avere poco a che fare con il programma C di partenza.
Sicuramente possono fare eccezione quei casi in cui
si vogliono sfruttare delle caratteristiche della cpu,
tipo MMX o cose simili, che non sono ben sfruttate dal
compilatore o che permettono scorciatoie che non sono esprimibili
nel linguaggio C.
Penso che da un punto di vista di sviluppo e manutenzione la
cosa migliore sia programmare in C ed eventualmente determinare
successivamente usare un profiler per vedere se ci siano delle sezioni
del programma cosi' critiche da meritarsi una versione in assembler.
ciao,
g.