Autore Topic: VC++ Implementation of Switch Statement  (Letto 12263 volte)

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
VC++ Implementation of Switch Statement
« il: 23 Aprile 2014, 09:22:41 »
Un interessante articolo che analizza l'implementazione dello Switch Statement sul compilatore Visual C++.

In poche parole utilizza un sistema di tabelle per garantire salti con complessità O(1) nel caso in cui le label siano consecutive, O(log N) negli altri casi, usando un binary search tree a compile time. Nei casi banali lo switch viene automaticamente convertito in un if-else, per mantenere comunque il minor tempo di esecuzione possibile.

http://www.codeproject.com/Articles/100473/Something-You-May-Not-Know-About-the-Switch-Statem

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Re:VC++ Implementation of Switch Statement
« Risposta #1 il: 23 Aprile 2014, 14:47:20 »
Se ne dicono tante di MS, ma VisualC++ spacca, c'e' poco da fare

Microsoft ha fatto tanti errori politici e commerciali (alcuni di stampo quasi mafioso), ma a livello tecnologico sono almeno 10 anni che regna, specialmente da quando hanno assunto il tipo danese ex Borland (l'inventore di Delphi e programmatore di Turbo Pascal) che è a capo del progetto .Net

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re:VC++ Implementation of Switch Statement
« Risposta #2 il: 23 Aprile 2014, 16:38:47 »
Bah; se parliamo di Visual Studio (IDE & such) allora posso concordare, ma parlando del compilatore C++ Microsoft non posso che dare un giudizio negativo (sopratutto quando parliamo di aderenza allo standard).

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Re:VC++ Implementation of Switch Statement
« Risposta #3 il: 23 Aprile 2014, 16:43:02 »
Bah; se parliamo di Visual Studio (IDE & such) allora posso concordare, ma parlando del compilatore C++ Microsoft non posso che dare un giudizio negativo (sopratutto quando parliamo di aderenza allo standard).

Io ho lavorato pesantemente con la versione 2005 di Visual C++ ed effettivamente masticava roba che tanto standard non era. Un po' come GCC diciamo.

Però ho letto cose molto positive su quest'ultima versione, ad esempio hanno rimosso quell'orrenda cosa che era il Managed C++ e hanno usato in maniera massiccia molte cose del C++11.

Comunque guardati anche C#, che è un linguaggio molto più moderno e ben progettato di C++. Su quel fronte MS ha fatto un ottimo lavoro.

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re:VC++ Implementation of Switch Statement
« Risposta #4 il: 23 Aprile 2014, 16:54:58 »
Però ho letto cose molto positive su quest'ultima versione, ad esempio hanno rimosso quell'orrenda cosa che era il Managed C++ e hanno usato in maniera massiccia molte cose del C++11.

Eppure anche nella 2013 non hanno totale supporto a C++11, sia come linguaggio che come librerie (aneddoto stupido che mi è capitato: con std::atomic_int non compilava e dava strani errori, mentre con std::atomic<int> funzionava tutto correttamente; il primo è definito come un typedef dell'altro!).

Visto che il software che stiamo sviluppando deve compilare anche con VC++ (per mia scelta) oltre che a Clang, mi sta molto a cuore lo sviluppo del compilatore Microsoft, ma non è possibile che ogni volta che facciamo il merge della codebase ci sia qualche puttanatina che su VC++ non va.
Spero seriamente che con VS2014 sistemino sta cosa, anche se gli altri compilatori (addirittura GCC!) sono già pronti per C++14 (Clang 3.4 ha totale supporto alla bozza dello standard attuale) :(.

Citazione
Comunque guardati anche C#, che è un linguaggio molto più moderno e ben progettato di C++. Su quel fronte MS ha fatto un ottimo lavoro.

Lo guarderò, ma a tempo perso, visto che il software che sviluppo deve essere multipiattaforma (Win/Mac/Linux e possibilmente altro, ma queste tre principalmente), e non voglio trafficare per trovare un compilatore C# che gira su Linux (per sviluppo) e/o librerie adatte (Mono l'ultima volta che ho controllato era un mezzo cesso).

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Re:VC++ Implementation of Switch Statement
« Risposta #5 il: 23 Aprile 2014, 17:01:01 »
probabilmente è ancora presto per buttare Mono nel cesso, ma a inizio mese MS ha rilasciato Open Source il suo compiler e gran parte del framework .Net http://roslyn.codeplex.com/ :)

Licenza Apache 2.0

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re:VC++ Implementation of Switch Statement
« Risposta #6 il: 23 Aprile 2014, 18:39:35 »
Boh, vedremo come si evolve la situazione.

Per il momento mi tengo stretto il mio bel elefante. ;D

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re:VC++ Implementation of Switch Statement
« Risposta #7 il: 23 Aprile 2014, 22:19:14 »
Un interessante articolo che analizza l'implementazione dello Switch Statement sul compilatore Visual C++.

In poche parole utilizza un sistema di tabelle per garantire salti con complessità O(1) nel caso in cui le label siano consecutive, O(log N) negli altri casi, usando un binary search tree a compile time. Nei casi banali lo switch viene automaticamente convertito in un if-else, per mantenere comunque il minor tempo di esecuzione possibile.

http://www.codeproject.com/Articles/100473/Something-You-May-Not-Know-About-the-Switch-Statem
Articolo molto bello e istruttivo. Danke! :)

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Re:VC++ Implementation of Switch Statement
« Risposta #8 il: 24 Aprile 2014, 10:47:14 »
Boh, vedremo come si evolve la situazione.

Per il momento mi tengo stretto il mio bel elefante. ;D

Già, aspettiamo :)

Quello che mi "preoccupa", in senso lato, è che il nuovo C++ è così diverso dal vecchio C++ '98 da risultare quasi un nuovo linguaggio a sè stante. Questo significa che i vecchi programmatori tenderanno per inerzia a non usare le novità e i nuovi programmatori non saranno attratti da questo mondo, continuando a preferire linguaggi diversi e più semplici (Java e C# attualmente sono i più diffusi in ambito enterprise).

Dal canto mio sto cercando di reintrodurre il C++ nel mio workflow quotidiano usando Qt per le app mobili, ma non mi sono addentrato nei meandri dei nuovi standard più per mancanza di tempo che altro.

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re:VC++ Implementation of Switch Statement
« Risposta #9 il: 24 Aprile 2014, 16:53:54 »
Quello che mi "preoccupa", in senso lato, è che il nuovo C++ è così diverso dal vecchio C++ '98 da risultare quasi un nuovo linguaggio a sè stante. Questo significa che i vecchi programmatori tenderanno per inerzia a non usare le novità e i nuovi programmatori non saranno attratti da questo mondo, continuando a preferire linguaggi diversi e più semplici (Java e C# attualmente sono i più diffusi in ambito enterprise).

Secondo me, non è poi "così diverso"; C++11 ha introdotto varie cose ma in realtà cose che i programmatori desideravano da molto e che sono di immediata applicabilità.

Esempi:
- l'uniform initialization che ti permette di inizializzare variabili e/o chiamare costruttori sempre usando le parentesi graffe; un esempio banale:
Codice: [Seleziona]
class Point {
    Point(int x, int y)
     ....
};
....
Color getPointColor(Point p);
....
Color c = getPointColor({4, 6});

- la parola chiave auto per determinare automaticamente all'inizializzazione il tipo di dato della variabile, comodo specialmente quando hai tipi templatizzati il cui nome è estremamente lungo (gli iterator per esempio).
- il range-based for (for(Tipo variabile : contenitore))
- Gli smart pointer sono migliorati e ce ne sono 4 tipi in base a come vuoi gestire l'oggetto
- Finalmente c'è un ordinamento della memoria ben definito e supporto di libreria per operazioni atomiche e thread di base.
- Il move semantics (1, 2)permette di scrivere il codice in modo più naturale anche lavorando con grossi oggetti, perchè limita al minimo il numero di copie che un oggetto subisce.

Tra queste cose che ho detto, le prime 4 possono essere usate fin da subito anche in un vecchio progetto, perchè non richiedono di reingegnerizzare il codice esistente; il threading ovviamente avvantaggia applicazioni parallele, anche se se una applicazione aveva bisogno dei thread, probabilmente si è creata le sue astrazioni e/o ha usato una libreria di terze parti.
Il move semantics è la cosa meno applicabile immediatamente, perchè un po' obbliga a ripensare a come trattare gli oggetti; in realtà in molti casi il lavoro di conversione può essere fatto solo nella classe stessa e il resto del codice continuerà a compilare e funzionare, però se l'applicazione è molto grande e con uno stile ben definito, può essere il caso di lasciarla com'è.

Quello che credo io è che, anche se magari C++ non crescerà prendendo nuovi programmatori, i correnti programmatori C++ avranno un tool molto più potente e pratico per costruire nuovi software o per perfezionarne vecchi, e secondo me non è una brutta cosa. :)


PS: i link che ho messo li ho presi velocemente per dare un riferimento a cosa sto dicendo; magari non sono i documenti migliori.
PPS: Dimenticavo le Lambda expression!

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re:VC++ Implementation of Switch Statement
« Risposta #10 il: 25 Aprile 2014, 06:58:31 »
Io lo considero un altro linguaggio, perché cambi il modo di programmare con C++0x11.

Comunque a me non piace come linguaggio perché, a parte la sintassi che mi sta proprio indigesta, è troppo complesso: per lavorarci e sfruttarlo al meglio serve tanta, tanta esperienza e un notevole esercizio di memoria.

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re:VC++ Implementation of Switch Statement
« Risposta #11 il: 25 Aprile 2014, 07:00:38 »
Le considerazioni fatte per lo switch statement non sono una prerogativa del compilatore Microsoft, ma di qualsiasi optimizing compiler.

Ci sarebbero tante cose da dire sullo switch statement del C (diverso dal case statement del Pascal) che rende difficoltosa la generazione della jump table. Alcune considerazioni fatte nell'articolo non valgono. Purtroppo non ho più tempo per dilungarmi nei forum :-(
Peccato, perché adoro questo tipo di discussioni. Ricordati che oggi è venerdì, e c'è pure il fine settimana davanti. :P
Citazione
Nei casi banali lo switch viene automaticamente convertito in un if-else, per mantenere comunque il minor tempo di esecuzione possibile.

I casi banali sono per n molti piccoli (n << 5), diversamente la jump table ha prestazioni migliori.

SE hai tempo, mi piacerebbe sapere quale sarebbe la masksearch instruction.

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re:VC++ Implementation of Switch Statement
« Risposta #12 il: 25 Aprile 2014, 22:52:23 »
Grazie per il paper. E' stato interessante per i dati presentati, anche se conferma l'idea che m'ero fatto intuitivamente su quest'argomento.

Comunque già da ieri mi frullano diverse idee su come implementare diversamente il caso di case/switch con diversi valori (quindi non pochi, ma nemmeno tantissimi), ma sparsi (entro un intervallo non troppo ampio). Ho in mente anche alcune soluzioni con hardware dedicato. Vediamo cosa posso tirare fuori in futuro.

P.S. Io passo ben più di 40 ore settimanali al computer: all'incirca il doppio. :-\

Dimenticavo: sul C++ sono d'accordo con te e con le citazioni che hai riportato. ;D

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re:VC++ Implementation of Switch Statement
« Risposta #13 il: 26 Aprile 2014, 04:04:22 »
Io lo considero un altro linguaggio, perché cambi il modo di programmare con C++0x11.

Se con C++0x11 parli di C++17, allora un po' posso darti ragione: per quella versione (se tutto va bene) è previsto l'inserimento di moduli (per sostituire gli #include), i concept lite (di cui posso capire la motivazione, però boh non mi convincono ancora) e molta altra roba sopratutto in libreria... quindi si, sarà un bel salto. ;D

In C++11, come dicevo prima, ci sono cosa nuove e importanti (move semantics in primis), però cose che già i programmatori volevano ed eventualmente cercavano di raggirare con altra programmazione; semplicemente ora possono scrivere nel modo più naturale senza fare workaround.
Non lo considero un "nuovo linguaggio", altrimenti una qualsiasi aggiunta di un nuovo algoritmo alla libreria di qualsiasi linguaggio implicherebbe un "nuovo linguaggio", perchè i programmatori possono usare quella versione invece di implementarsi la propria. :D


Posso catalogarlo come il peggior libro che ho letto sul language design e software engineering,

Forse perchè non vuole essere un libro sul "language design e software engineering" ma solo sulla storia e evoluzione del C++, che sicuramente non è stato un lavoro da accademia ma un'evoluzione "sul campo" (con tutti i problemi che ciò comporta).

Però non posso dire niente perchè non lo ho letto; ho da leggere "A Tour of C++" così for the lulz, visto che è menzionato in quel video che ho linkato.

Secondo me, non è poi "così diverso"

Il C++ per come venne concepito da Stroustrup non ha nulla a che vedere con il C++ di oggi.

Posso essere d'accordo, però la discussione iniziale era C++11 vs. vecchio standard (che tecnicamente sarebbe C++03, però a tutti gli effetti si considera C++98), e in questo lo considero "non così diverso".

Oggi non si può dire ciò sui compilatori C++ e credo che per i suoi progetti oggi nemmeno lo utilizzi. Lo stesso Stroustrup fa capire in alcune parti che da quando si è messo in mezzo il working group del C++ standard committee, il suo linguaggio ha perso di semplicità. Addirittura ha scritto che alcune delle feature aggiunte successivamente sono pure troppo per lui.

Guarda, l'idea che mi son fatto io (anche vedendo dove stanno puntando con le nuove revisioni), è che hanno visto come il C++ stia perdendo spazio ad altri linguaggi più snelli e pratici come Java e C# (oddio, definire pratico e snello il Java... ::) è un azzardo, però dai diciamolo for the sake del discorso), e di come hanno lasciato passare questo fatto per troppo tempo (C++11 c'ha messo i suoi bei 13 anni a completarsi), e quindi stiano cercando di ripulirlo e modernizzarlo.

Il problema però è che devono rimanere il più possibile compatibili con tutti i vecchi sorgenti decennali ancora richiesti (altrimenti è facile fare un nuovo linguaggio!), quindi l'unico modo che hanno è aggiungere funzionalità; questa cosa si vede un po' in tutto, prendiamo ad esempio OpenGL che nelle versioni 4+ sta diventando una API molto snella... se consideri solo le cose più nuove. Quì il problema è un po' diverso, perchè se mentre col C++ puoi usare l'ultimissima versione che il compilatore supporta, con OpenGL devi tener conto della versione che i driver dei tuoi clienti supportano, quindi anche io ad esempio devo programmare su un OpenGL <3.3 (principalmente perchè come requisito il programma deve funzionare anche su Linux con i driver open source, che sono arrivati solo a 3.3). Come reference posso dire che le funzioni molto comode che mi servirebbero sono in OpenGL 4.3 e 4.4.

Ora, ritornando al C++, è vero che ha tante cose dentro, ma non è detto che bisogna usarle, anche perchè ci sono robe introdotte malamentre e praticamente inusabili (esempio classico è la parola chiave export, che ha una funzione talmente assurda e complessa che esiste un solo compilatore in grado di compilarla, e gli sviluppatori dello stesso compilatore scoraggiano gli altri programmatori a provare a implementarla).

Io ritengo di usare un buon set di funzionalità del C++ (programmazione procedurale, oggetti, ereditarietà, classi virtuali pure [a mo di interfaccia], template [per un momento abbiamo anche usato template metaprogramming, poi son cambiati un po' i requisiti e rigirando il codice non ne avevamo più bisogno], molte contenitori e funzioni di libreria), e ora spero di usare di più ancora le nuove funzionalità di C++11; molte come la move semantics la uso già (sia nelle classi che scrivo io, sia sfruttandone il supporto da parte della libreria standard), e fra non molto sfrutterò anche i thread e la sincronizzazione (almeno così non dovrò includere boost.thread come dipendenza).

A me piacerebbe TANTISSIMO che per C++17 mettessero molte cose come "deprecated" e con uno switch da compilatore per disabilitarle tutte; lo attiverei subito. ;D

Aggiungo come mio solito fare un quote sul C++:
Citazione
If you think C++ is not overly complicated, just what is a protected abstract virtual base pure virtual private destructor and when was the last time you needed one?
— Tom Cargill

A me pare una supercazzola; come fa a essere protected e private allo stesso tempo? ???

Come chicca finale, imparate a memoria ciò:
Citazione
    The body of a destructor is executed before the destructors for member objects. Destructors for nonstatic member objects are executed before the destructors for base classes. Destructors for nonvirtual base classes are executed before destructors for virtual base classes. Destructors for nonvirtual base classes are executed in reverse order of their declaration in the derived class. Destructors for virtual base classes are executed in the reverse order of their appearance in a depth-first left-to-right traversal of the directed acyclic graph of base classes; “left-to-right” is the order of appearance of the base class names in the declaration of the derived class.

– Bjarne Stroustrup, The C++ reference manual, section 12.4.

In realtà non è poi così strambo: ti dice che prima distrugge te, poi distrugge i tuoi membri (nell'ordine inverso di costruzione aggiungerei), e poi passa a distruggere le classi base. Sulla storia del grafo aciclico devo ragionarci un po' su, ma credo che intenda semplicemente dire che, nell'ordine in cui hai dichiarato le classi da cui erediti, lui prende la prima e distrugge tutti i suoi discendenti, poi prende il secondo etc.
Dammi un po' di tregua, son le 4am! ;D *


* Ecco in questo caso puoi rispondere che "Eeeeh in <linguaggio> puoi capirlo anche se sono le 4 di mattina etc etc. :-P"

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re:VC++ Implementation of Switch Statement
« Risposta #14 il: 26 Aprile 2014, 06:36:18 »
Appunto. Perché altri linguaggi non hanno quella mostruosa complessità del C++. ;)

Tags: