2012-05-09 15 views
9

Sono un po 'confuso dalle dichiarazioni #define. Nelle biblioteche, sembrano essere un mezzo di comunicazione tra diversi file, con un sacco di #ifdef s e #ifndef s.C: Le direttive #define sono globali?

Detto questo, ora ho due file file1.c e file2.c compilato insieme, con #define TEST 10 all'interno file2.c. Eppure, quando uso TEST all'interno file2.c il compilatore fornisce il seguente messaggio di errore:

'TEST' undeclared (first use in this function) 

Sono #define direttive globale?

+0

Dipende da dove sono definiti. – Nick

+0

'# define' è una direttiva preprocessore - semplifica semplicemente le sostituzioni di testo in fase di compilazione - solo l'unità di compilazione e tutti i file' # include'd vedranno * a '# define'. –

risposta

13

#define s non sono globali, sono solo una sostituzione dove mai sono utilizzati (se dichiarato nella stessa unità di compilazione)

Sono non globali, sono non simboli, sono irrilevante al collegamento, sono rilevanti solo al pre-compilazione.

+0

Cosa intendi con "unità compilata"? Come posso avere 'file1.c' e' file.2' nella stessa unità di compilazione? – Randomblue

+1

No. sono compilati separatamente. e gallina collegati tra loro. Hai familiarità con il processo di compilazione C? – MByD

+0

Quindi 'file1.c' e' file2.c' non possono mai essere nella stessa unità di compilazione? – Randomblue

4

#define d macro sono globali in quanto non seguono le normali regole di ambito C. La sostituzione testuale dalla macro verrà applicata (quasi) ovunque il nome della macro viene visualizzato dopo il suo #define. (Notevoli sono le eccezioni se il nome della macro fa parte di un commento o parte di una stringa letterale.)

Se si definisce una macro in un file di intestazione, qualsiasi file che #include s quello file di intestazione erediterà quella macro (se essi lo vuoi o no), a meno che non lo definiscano esplicitamente con #undef.

Nel proprio esempio, file2.c non conosce la macro TEST. Come fa a sapere di prendere il #define da file1.c? Per magia? Poiché le macro eseguono la sostituzione testuale sul codice sorgente, non vi è alcuna rappresentazione nei file oggetto generato. file2.c pertanto deve conoscere la regola di sostituzione stessa e, se si desidera condividerla su più file, è necessario che #define risieda in un file di intestazione comune che i file .c#include.

Se stai chiedendo in particolare su come molti dei #ifdef s che si vedono nelle biblioteche funzionano, molti di loro sono probabilmente controllando contro nomi di macro predefiniti fornite dall'ambiente di compilazione. Ad esempio, un compilatore C99 definisce una macro __STDC_VERSION__ che specifica la versione della lingua; un compilatore Microsoft definisce una macro _MSC_VER. La maggior parte dei compilatori consente anche di definire semplici macro come argomenti da riga di comando. Ad esempio, è possibile compilare il codice tramite gcc -DNDEBUG file1.c per compilare file.c con NDEBUG definito per disabilitare assert s.

+0

Thx per informazioni utili – Hydro

1

si dovrebbe creare un file1.h e inserire i propri valori lì. Quindi in file2.c

#include "file1.h" 

facile come una torta :)

0

Nel caso in cui qualcuno legge questo in seguito, e per aggiungere alcune informazioni pratiche:

  • Alcuni ambienti come Atmel, vs, o iar, è consentire per definire le direttive #define globali. Fondamentalmente passano questi valori definiti al precompilatore in qualche formato della riga di comando.
  • Si può fare lo stesso nei comandi batch o makefile, ecc.
  • Arduino aggiunge sempre una variante di scheda (di solito si trova in hardware \ arduino \ varianti) a tutte le compilazioni. A quel punto puoi creare una nuova scheda che contiene le tue direttive definitive globali e usarla in questo modo. Ad esempio, è possibile definire una scheda mega2560 (debug) fuori dal mega2560 originale che contiene alcune direttive di debug. Aggiungerai un riferimento a quella variante in "boards.txt", copiando incollando del testo e modificandolo correttamente.

Alla fine della giornata, sarà necessario assegnare al compilatore in un modo o nell'altro la direttiva globale hfile o globale.

Problemi correlati