I macro C++ sono semplici sostituzioni di testo.
All'avvio del compilatore, il tuo LOGIC_ONE
è già stato sostituito dal precompilatore da 1
. È proprio come se avessi scritto 1
subito. (Il che, in questo caso, è un int letterale ...)
Modifica per includere la discussione nei commenti:
Se voi (o qualcun altro con accesso al codice) cambia il vostro #define LOGIC_ONE 1
-#define LOGIC_ONE "1"
cambierebbe il suo comportamento nel programma e diventa un valore letterale const char[]
.
Edit:
Dato questo post ha ottenuto più attenzione di quanto mi aspettassi, ho pensato aggiungere i riferimenti al C++ 14 Standard per quelli curiosi:
2.2 Fasi della traduzione [lex.phases]
(...)
4. Le direttive di preelaborazione vengono eseguite, le chiamate di macro vengono espanse e le espressioni di operatore unarioPragma vengono eseguite. (...) Tutte le direttive di pre-elaborazione sono quindi cancellate.
(...)
7. I caratteri di spazio bianco che separano i token non sono più significativi. Ogni token di preelaborazione viene convertito in un token. (2.6). I token risultanti sono analizzati sinteticamente e semanticamente e tradotti come un'unità di traduzione.
Come indicato, le macro vengono sostituite nella fase 4 e non sono più presenti in seguito. L'analisi "sintattica e semantica" ha luogo nella fase 7, dove il codice viene compilato ("tradotto").
letterali interi sono specificati in
2.13.2 letterali interi [lex.icon]
(...)
Un numero intero letterale è una sequenza di cifre che non ha periodo o esponente parte, con facoltativo che separa le virgolette singole che vengono ignorate nel determinare il suo valore. Un valore letterale intero può avere un prefisso che ne specifica la base e un suffisso che ne specifica il tipo.
(...)
Tabella 5 - Tipi di letterali interi
Suffix | Decimal literal | Binary, octal, or hexadecimal literal
-----------------------------------------------------------------------------
none | int | int
| long int | unsigned int
| long long int | long int
| | unsigned long int
| | long long int
| | unsigned long long int
-----------------------------------------------------------------------------
u or U | unsigned int | unsigned int
| unsigned long int | unsigned long int
| unsigned long long int | unsigned long long int
-----------------------------------------------------------------------------
l or L | long int | long int
| long long int | unsigned long int
| | long long int
| | unsigned long long int
-----------------------------------------------------------------------------
Both u or U | unsigned long int | unsigned long int
and l or L | unsigned long long int | unsigned long long int
-----------------------------------------------------------------------------
ll or LL | long long int | long long int
| unsigned long long int
-----------------------------------------------------------------------------
Both u or U |unsigned long long int | unsigned long long int
and ll or LL | |
Le stringhe sono specificate nella
2.13.5 stringa letterali [lex.string]
(...)
1 Una stringa letterale è una sequenza di caratteri (come definita in 2.13.3) circondata da virgolette, facoltativamente preceduta da R, u8, u8R, u, uR, U, UR, L, rLR, come in " ... ", R" (...) ", u8" ... ", u8R" ** (...) ** ", u" ... ", uR" * ~ (...) * ~ ", U" ... ", UR" zzz (...) zzz ", L" ... "o LR" (...) ", rispettivamente.
(...)
6 Dopo la fase di conversione 6, un letterale di stringa che non inizia con un prefisso di codifica è un normale stringa letterale e viene inizializzato con i caratteri specificati.
7 Una stringa letterale che inizia con u8, come u8 "asdf", è una stringa letterale UTF-8.
8 I valori letterali stringa normali e i valori letterali stringa UTF-8 vengono anche chiamati valori letterali stringa ristretti. Un letterale stringa stretto ha tipo "matrice di n const char
", dove n è la dimensione della stringa come definito di seguito e ha la durata di archiviazione statica (3.7).
Per vedere ciò che il preprocessore fa, passa '-E' al compilatore. (msvc, gcc, clang all accetta '-E') – Ben