c++ - Cosa significa "commento#pragma"?




visual-c++ macros (4)

Li ho sempre definiti "direttive del compilatore". Dirigono il compilatore a fare cose, ramificazioni, incluse librerie come mostrato sopra, disabilitando errori specifici ecc., Durante la fase di compilazione.

Le aziende di compilazione di solito creano le proprie estensioni per facilitare le loro funzionalità. Ad esempio, (credo) Microsoft ha avviato l'accordo "#pragma once" ed era solo nei prodotti MS, ora non ne sono così sicuro.

Direttive Pragma Include "commento #pragma" nella tabella che vedrai.

HTH

Sospetto che GCC, ad esempio, abbia il proprio set di # pragma.

Cosa significa il #pragma comment nel seguito?

#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")

#pragma comment è una direttiva del compilatore che indica a Visual C ++ di lasciare un commento nel file oggetto generato. Il commento può quindi essere letto dal linker quando elabora i file oggetto.

#pragma comment(lib, libname) dice al linker di aggiungere la libreria 'libname' all'elenco delle dipendenze della libreria, come se l'avessi aggiunta nelle proprietà del progetto su Linker->Input->Additional dependencies

Vedi il commento di #pragma su MSDN


Questi link nelle librerie selezionate in MSVC ++.


Bene, sono abbastanza sorpreso che le alternative a questa sintassi non siano state menzionate. Un altro meccanismo comune (ma più vecchio) è quello di chiamare una funzione che non è definita e affidarsi all'ottimizzatore per compilare la chiamata della funzione se la propria asserzione è corretta.

#define MY_COMPILETIME_ASSERT(test)              \
    do {                                         \
        extern void you_did_something_bad(void); \
        if (!(test))                             \
            you_did_something_bad(void);         \
    } while (0)

Mentre questo meccanismo funziona (purché le ottimizzazioni siano abilitate) ha il rovescio della medaglia di non riportare un errore finché non si collega, momento in cui non riesce a trovare la definizione per la funzione you_did_something_bad (). Ecco perché gli sviluppatori del kernel iniziano a utilizzare trucchi come le larghezze dei campi di bit di dimensioni negative e gli array di dimensioni negative (il più tardi ha smesso di generare build in GCC 4.4).

In simpatia per la necessità di asserzioni in fase di compilazione, GCC 4.3 ha introdotto l' attributo della funzione di error che consente di estendere questo concetto precedente, ma di generare un errore in fase di compilazione con un messaggio a scelta - non più criptico "negativo array "messaggi di errore!

#define MAKE_SURE_THIS_IS_FIVE(number)                          \
    do {                                                        \
        extern void this_isnt_five(void) __attribute__((error(  \
                "I asked for five and you gave me " #number))); \
        if ((number) != 5)                                      \
            this_isnt_five();                                   \
    } while (0)

Infatti, da Linux 3.9, ora abbiamo una macro chiamata compiletime_assert che usa questa funzione e la maggior parte delle macro in bug.h sono state aggiornate di conseguenza. Tuttavia, questa macro non può essere utilizzata come inizializzatore. Tuttavia, utilizzando le espressioni di istruzioni (un'altra estensione C di GCC), è possibile!

#define ANY_NUMBER_BUT_FIVE(number)                           \
    ({                                                        \
        typeof(number) n = (number);                          \
        extern void this_number_is_five(void) __attribute__(( \
                error("I told you not to give me a five!"))); \
        if (n == 5)                                           \
            this_number_is_five();                            \
        n;                                                    \
    })

Questa macro valuterà il suo parametro esattamente una volta (nel caso abbia effetti collaterali) e creerà un errore in fase di compilazione che dice "Ti ho detto di non darmi un cinque!" se l'espressione è uguale a cinque o non è una costante in fase di compilazione.

Quindi, perché non usiamo questo invece dei campi di bit di dimensioni negative? Purtroppo, ci sono attualmente molte restrizioni all'uso delle espressioni di istruzioni, incluso il loro uso come inizializzatori costanti (per costanti di enumerazione, larghezza del campo di bit, ecc.) Anche se l'espressione dell'istruzione è completamente costante il suo sé (cioè può essere pienamente valutata al momento della compilazione e altrimenti passa il test __builtin_constant_p() ). Inoltre, non possono essere utilizzati al di fuori di un corpo di una funzione.

Si spera che GCC corregga presto queste carenze e consenta l'uso di espressioni di dichiarazione costanti come inizializzatori costanti. La sfida qui è la specifica del linguaggio che definisce ciò che è un'espressione costante legale. C ++ 11 ha aggiunto la parola chiave constexpr solo per questo tipo o cosa, ma non esiste alcuna controparte in C11. Mentre C11 ha ottenuto asserzioni statiche, che risolveranno parte di questo problema, non risolverà tutte queste carenze. Quindi spero che gcc possa rendere disponibile una funzionalità di constexpr come estensione via -std = gnuc99 & -std = gnuc11 o alcuni di essi e permetterne l'uso sulle espressioni di dichiarazione et. al.





c++ visual-c++ macros