Per lo sviluppo e la compilazione di sorgenti C++ esistono numerose soluzioni per ogni piattaforma, sia open source che commerciali.
In questa lezione analizzeremo gli strumenti maggiormente diffusi, soprattutto quelli gratuiti, ed il supporto offerto da ognuno di essi alle varie versioni dello standard C++.
Ambienti di sviluppo per C++
Che sia per lavoro o per apprendimento, quando si parla di sviluppo software è sempre bene dotarsi di strumenti comodi e adatti allo scopo specifico.
Infatti, sebbene si possa procedere allo sviluppo di un'applicazione generica dotandosi semplicemente di un editor di testo e del compilatore appropriato per la nostra piattaforma, è sempre consigliabile fare uso di uno strumento professionale, quale un Integrated Desktop Environment (IDE), dotato almeno delle seguenti funzionalità:
- evidenziazione della sintassi (syntax-highlight);
- completamento automatico (auto-completion);
- gestione di progetto.
Chi ha familiarità con l'uso di un qualsiasi linguaggio di programmazione ha ben chiara l'utilità dei primi due elementi al fine di rendere agevole la scrittura del codice e la sua revisione in caso di modifiche o correzioni.
La possibilità di gestire un corpus di sorgenti strutturato su più files diventa invece rilevante via via che le nostre applicazioni crescono e diventano complesse.
Fortunatamente esistono numerosi IDE multipiattaforma che ci consentono di ritrovare il medesimo ambiente di sviluppo su sistemi differenti. Come esempi citamo Eclipse, NetBeans, CodeLite, Code::Blocks e Qt Creator, che possono essere usati su Windows, Linux e Mac OS.
Esistono poi prodotti specifici per piattaforma, come ad esempio Visual Studio Community per Windows e Xcode per Mac OS.
Qualunque sia la nostra preferenza, è importante infine accertarsi che il compilatore usato dal nostro IDE sia conforme allo standard del linguaggio che intendiamo adottare per lo sviluppo delle nostre applicazioni. Nella prossima sezione discuteremo infatti il supporto offerto dai vari compilatori allo standard C++.
Compilatori C++
Esistono numerosi compilatori per C++ gratuitamente disponibili per ogni piattaforma. Ognuno di questi si differenzia per performance, livelli di ottimizzazione previsti per differenti architetture hardware, e standard del linguaggio supportati.
Tra i progetti open source annoveriamo GCC (Gnu Compiler Collection), LLVM (Low Level Virtual Machine), con il suo front-end specifico per C/C++ Clang, MinGW (Minimalist GNU for Windows) e MinGW-w64, un progetto parallelo a MinGw che fornisce il supporto alle archietture a 64 bit.
I primi due hanno una vocazione multi-piattaforma, anche se la procedura di installazione su Windows è alquanto complicata rispetto a quella prevista per i sistemi Unix. MinGW e MinGW-w64 sono invece reimplementazioni specifiche per il sistema Microsoft Windows di alcuni tool sviluppati e mantenuti nell'ambito del progetto GNU.
Tuttavia, se non avete remore nell'usare un compilatore non open source, per i sistemi Windows è possibile usare MSVC++, il compilatore distribuito gratuitamente da Microsoft, incluso a partire dal 2015 nel pacchetto Visual C++ Build Tools.
Compilare da riga di comando in ambienti Unix
Probabilmente il modo più semplice per iniziare a programmare in C++ consiste nel dotarsi di un sistema Unix-like, come Linux o Mac OS, ed installare GCC.
Nel caso di Linux possiamo optare per un'installazione vera e propria o per l'uso di una macchina virtuale.
Molte distribuzioni mettono a disposizione meta-pacchetti che consentono di installare l'ecosistema completo di sviluppo per C++. Su distribuzioni Debian-based questo pacchetto è noto con il nome build-essential, mentre su distribuzioni RPM-based, i tools di sviluppo per C++ sono inclusi nel gruppo Development Tools.
Il nome dell'eseguibile del compilatore C++ di GCC è g++.
Per compilare un solo file sorgente con g++ è sufficiente eseguire il seguente comando in un terminale:
g++ main.cpp -o test
Dove main.cpp è il file che contiene il nostro codice sorgente e -o <name> è l'opzione usata per dare un nome al file eseguibile. Nel caso questa opzione sia assente, il nome di default è a.out.
Questo è sufficiente per molti degli esempi che verranno mostrati nelle lezioni successive. Tuttavia, nel caso sia necessario, si può estendere la compilazione a più file sorgenti con il comando:
g++ *.cpp -o test
In realtà, il più delle volte, è più comodo lasciare che il processo di compilazione sia avviato mediante un ambiente di sviluppo specifico. Pertanto in quest'ottica, non analizzeremo nel dettaglio le varie opzioni di g++ per la compilazione, il linking la configurazione e l'ottimizzazione. Salvo casi particolari, ci limiteremo infatti a demandare allo IDE di nostra preferenza la responsabilità di compilare i nostri sorgenti e ci concetreremo esclusivamente sui costrutti sintattici del linguaggio e la loro semantica.
Standard del C++
Gli standard del linguaggio C++ sono informalmente identificati dalla sigla c++XX, dove XX rappresenta le ultime due cifre dell'anno di ratificazione dello standard.
La prima versione ISO è nota come c++98, ed è stata per lungo tempo la versione di riferimento per tutti gli ambienti di sviluppo, integrata successivamente dalla versione successiva, detta c++03, che ne ha costituito più una rettifica che un'espansione vera e propria. Bisogna infatti attendere la versione c++11 per osservare notevoli potenziamenti nella semantica del linguaggio. Questa versione dello standard, soggetta ad un lungo processo di revisione, era stata provvisoriamente chiamata c++0x, nella speranza che la ratifica definitiva giungesse a compimento prima del 2010.
Ad essa ha fatto seguito la versione c++14, che integra ulteriori espansioni dei costrutti sintattici del linguaggio. Attualmente è in fase di revisione la versione c++1z prevista per il 2017.
Il supporto agli standard più recenti, da quello del 2011 in poi, non è universalmente garantito da tutti i compilatori, ed in alcuni casi è necessario abilitarlo esplicitamente. Tuttavia, nella maggior parte dei casi si tende ad aderire alle versioni più recenti. Ne sono un esempio GCC, che dalla versione 6.1 adotta già c++14 come standard di default, e Clang che, sebbene si basi sullo standard c++98, accetta implicitamente molte delle estensioni di c++11.
La tabella seguente illustra lo stato attuale del supporto offerto dai compilatori sopra citati.
Standard | GCC | Clang | MinGW | MinGW-w64 | MSVC++ |
---|---|---|---|---|---|
c++1z | 6.0 parziale | 3.5 parziale | - | - | 2015 parziale |
c++14 | 5.1 | 3.4 | 5.0 parziale | 4.0 parziale | 2013 parziale |
c++11 | 4.8.1 | 3.3 | 4.0 parziale | 3.0 parziale | 2012 parziale |
Ovviamente, ad ogni nuova release, ogni compilatore tende ad allinearsi con lo standard più recente, ma per esigenze di compatibilità potremmo essere obbligati ad usare una versione antecedente che potrebbe non supportare i costrutti usati nel nostro codice sorgente.
Quando ciò si verifica, il processo di compilazione produce una serie di messaggi di errore non facilmente decifrabili, che potrebbero indurci alla ricerca di inesistenti errori sintattici. Pertanto se si vuole sperimentare una versione molto recente dello standard del linguaggio, o addirittura una in fase sperimentale, è bene accertarsi che il nostro compilatore sia compatibile.