[Visual-C++] Le macro di #ifdef

giovedì 09 ottobre 2008 - 19.12

xshell Profilo | Newbie

Buongiorno a tutti.

Curiosando in vari sorgenti C e C++, ho notato l'uso della direttiva #ifdef. Ne ho compreso la funzionalità, però non sò ancora quale macro un compilatore può accettare per, ad esempio, verificare che una data libreria esista e compilare il codice sorgente che la utilizza, oppure per inserire il supporto a vari sistemi operativi. Un codice sorgente riportava le righe seguenti:

#ifdef HAVE_CONFIG_H #include <config.h> #endif #ifdef STDC_HEADERS #include <stdlib.h> #include <string.h> #endif

Non sò se sia la sezione del forum adatta, però mi chiedo: le macro di #ifdef sono definite dal compilatore, dal linguaggio di programmazione o dal programmatore stesso? Se sono definite dal compilatore, c'è una differenza tra i vari compilatori (Visual Studio, Borland-C++, GCC, ...) nella definizione di tali macro e dove posso trovarle (ho cercato nella documentazione dei compilatori, ma non ho trovano un bel niente)?

Ringrazio in anticipo per le eventuali risposte.

aiedail92 Profilo | Expert

Ciao

#ifdef non è una macro, è una direttiva per il preprocessore.

In pratica un file di codice c\c++ viene passato prima dal preprocessore e poi viene effettivamente compilato. Quello che fa la direttiva #ifdef è escludere dalla compilazione il codice fra la direttiva e la corrispondente #endif di chiusura nel caso in cui la macro non sia definita

Quindi nel codice

#ifdef HAVE_CONFIG_H #include <config.h> #endif #ifdef STDC_HEADERS #include <stdlib.h> #include <string.h> #endif

verrà incluso il file di intestazione "config.h" solo se la macro HAVE_CONFIG_H sarà definita; e i file "stdlib.h" e "string.h" solo se sarà definito STDC_HEADERS.

Non esiste una file con la definizione della direttiva in quanto fa parte del preprocessore.

Luca

xshell Profilo | Newbie

Sì, ma lo sapevo che #ifdef è una direttiva (tutte le parole chiave che iniziano con # lo sono e l'ho anche specificato nel mio precedente post con "l'uso della direttiva #ifdef") però volevo sapere quali erano le macro che potevo aggiungere... come macro intendo, ad esempio, HAVE_CONFIG_H... non sò se sto utilizzando il termine giusto... comunque, più precisamente, volevo conoscere da quale fonte posso prendere queste macro o costanti (oppure chiamiamole "etichette")... perché se io non vedevo che HAVE_CONFIG_H serviva per verificare la presenza dell'header config.h, come facevo? Non credo si possano inventare... Esiste una qualche documentazione? E se sì, dove la reperisco?

Per essere più esplicito: se io non curiosavo su un codice sorgente altrui, non avrei mai saputo quale etichetta inserire in #ifdef per verificare la presenza di config.h. Mi è quindi venuto il seguente dubbio: HAVE_CONFIG_H è definito da qualche parte o lo potevo chiamare anche PIPPO_PINCOPALLO? Se volessi verificare il sistema operativo su cui si deve compilare il codice specifico, ad esempio, per linux o macos, quale etichetta dovrei inserire?

aiedail92 Profilo | Expert

La macro HAVE_CONFIG_H devi definirla tu in base a ciò che serve: se hai il file config.h puoi definire la macro, in questo modo il file viene incluso, se invece sai di non averlo e il codice è appositamente progettato, puoi non definire la macro e non includere quindi il codice.

La macro puoi definirla sia da codice che direttamente dalle opzioni di compilazione (/DHAVE_CONFIG_H) in questo caso non dovrebbe espandersi in niente, dovrebbe servire solo come verifica, comunque non si può dire così a priori, ogni progetto ha le sue definizioni e macro.

Luca

xshell Profilo | Newbie

Ah, ok. Grazie.

Solo due ultime domande: se volessi definire una macro, per esempio... PIPPO, per includere la libreria pippo.h, cosa dovrei scrivere per definirla da codice? Hai detto che posso definirle tramite opzioni di compilazione. In Visual Studio dove dovrei andare e cosa dovrei scrivere?

Ciao.

aiedail92 Profilo | Expert

Usa la direttiva #define:

#define PIPPO #ifdef PIPPO #include <pippo.h> #endif

Per rimuovere la definizione (se potrà servirti) invece si usa la direttiva #undef:

#undef PIPPO

Per le opzioni di compilazione clicka col destro sul progetto in esplora soluzioni e quindi su proprietà. Per le definizioni del preprocessore guarda nel nodo "C/C++ -> Preprocessore"

Luca

xshell Profilo | Newbie

Si, ma se scrivo semplicemente #define PIPPO, le funzionalità di PIPPO non vengono descritte... come fa il compilatore, ad esempio, con #ifdef _WINDOWS, #ifdef _LINUX ecc, ha capire che deve comportarsi in una determinata maniera a seconda del sistema operativo?

aiedail92 Profilo | Expert

Sta al programmatore definire la macro in base al sistema operativo con cui sta compilando. Se hai un codice che può essere compilato sia su windows che su linux, quando compili da windows dovrai definire la macro _WINDOWS, e quando compili da linux la macro _LINUX.

Luca

xshell Profilo | Newbie

Appunto... il fatto sta che nel codice che ho visto, c'era solo #ifdef _sun_ per indicare che il codice seguente deve essere compilato se si è in ambiente solaris, ma scorrendo tutto il codice, non ho visto alcuna definizione di _sun_, quindi non credo che il programmatore abbia definito _sun_ ma piuttosto credo che abbia usato una ben predefinita etichetta... quindi --> ENIGMA...... se il programmatore l'avesse definita, dovrebbe essere presente il codice per l'etichetta _sun_, ma non è presente. Ecco perché mi sono sorti dei dubbi... adesso tu mi stai dicendo che l'etichetta non è predefinita ma deve essere definita dall'utente... e allora come ha fatto quel programmatore a scrivere un programma senza definire l'etichetta?

aiedail92 Profilo | Expert

Forse la definizione era inserita all'interno delle impostazioni di compilazione, che non risiedono nel codice, ma nel file del progetto. È anche possibile che il compilatore identifichi automaticamente la piattaforma e definisca automaticamente le macro.

Luca

xshell Profilo | Newbie

Ma allora se mi dici che "è anche possibile che sia il compilatore a definire la macro in base al sistema operativo", non fai altro che confermare la mia iniziale tesi. Quindi... come fa questo compilatore e il computer, che intrinsecamente è "stupido", a definire la macro? Quale macro? Va beh, non importa.

aiedail92 Profilo | Expert

No, importa eccome

Se provi a vedere le proprietà di un progetto C++ ti accorgi che in alto puoi scegliere Configurazione e Piattaforma. Scegliendo la piattaforma è possibile (dico possibile perchè vedo nella configurazione del processore che definisce la macro _WINDOWS) che il compilatore di visual studio generi automaticamente la macro _WINDOWS. È altresì possibile che altri compilatori (Borland, GCC ecc) non abbiano quest'opzione, dato che non li conosco...

Luca

xshell Profilo | Newbie

Grazie!
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5