2013-07-07 15 views
5

In C++ (e C) abbiamo la direttiva #pragma che ha fondamentalmente effetti di implementazione definiti. Tuttavia, ci sono dei limiti a ciò che la direttiva può fare? (Si noti che sto chiedendo ciò che la norma consente, non su ciò che i compilatori reali effettivamente fare.)Che cosa consente lo standard #pragma?

Quello che sto certo #pragma può fare:

  • permettono di selezionare una delle diverse opzioni di compilazione che tutto porta a C++ valido. Ad esempio, seleziona uno dei vari ABI disponibili o cambia alcune opzioni di implementazione definite.

Quello che immagino è consentito, ma non sono sicuro:

  • Lasciare che il compilatore di accettare il codice altrimenti illegale senza l'emissione di un diagnostico (per esempio, un compilatore potrebbe decidere di sostenere un nuovo built -in tipo long long long, ma qualsiasi codice che utilizza che avrebbe dovuto emettere un diagnostico;. questa diagnostica potrebbe quindi essere soppresso con ad esempio #pragma long long long

  • Consentire al compilatore di rifiutare il codice altrimenti legale, per esempio ci potrebbe essere un #pragma strict che induce il compilatore a segnalare come errore l'uso di alcune funzioni di libreria e/o costrutti di linguaggio considerati non sicuri.

Quello che realmente dubbio è consentito, ma non sono sicuro che sia:

  • Lasciare che il compilatore di modificare la semantica di codice legale per qualcosa di diverso (per esempio, si supponga che un fornitore del compilatore ha ritenuto una buona idea se la condizione for fosse una postcondizione (come in do ... while), e definito #pragma for postcondion per commutare il senso di for conseguenza.

Il motivo per cui dubito di quest'ultimo è che al compilatore è permesso di ignorare qualsiasi pragma che non riconosce, e quindi un cambiamento di semantica da parte di un pragma farebbe sì che lo stesso programma abbia semantica diversa su diversi compilatori.

Tuttavia, cosa consente effettivamente lo standard? E ci sono cose che sono permesse, ma che non sono coperte dalla mia lista sopra?

+0

Dubito che le lunghe cose lunghe siano consentite: '# pragma' può essere ignorato dai compilatori comunque. –

+0

@Alexandre Certo, ma non riesco a vedere come questo è un problema per l'esempio che ha dato. Se il compilatore supportava 'long long long', supportava anche' # pragma' che sopprimeva l'avviso emesso al momento del suo utilizzo. Inoltre, come è diverso da un pragma di soppressione degli avvertimenti più generico? –

risposta

5

lo standard è abbastanza chiaro su questo:

[cpp.pragma] Una direttiva al preprocessore della forma

#pragma pp-tokensopt new-line 

provoca l'attuazione a comportarsi in un modo definito dall'implementazione.Il comportamento potrebbe causare il fallimento della conversione o il comportamento del traduttore o del programma risultante in modo non conforme. Qualsiasi pragma non riconosciuto dall'implementazione viene ignorato.

Il compilatore può quindi fare praticamente tutto ciò che vuole vedendo uno #pragma.

1

Il compilatore è autorizzato a fare assolutamente tutto, purché sia ​​documentato. Una versione molto vecchia di gcc, dopo aver visto qualsiasi pragma, usato per fermare la compilazione e tentato di localizzare e lanciare uno dei giochi in modalità testo che esistevano allora. Il che era perfettamente conforme allo standard perché c'era una sezione su di esso nella guida dell'utente.

+0

IMHO il vecchio comportamento di gcc rientrerebbe in "rifiuto del codice legale altrimenti" (dove il codice * all * è stato rifiutato e l'avvio di un gioco è solo un modo abbastanza creativo di emettere una diagnosi). – celtschk

+0

Non ho visto nulla di scritto che la documentazione sia richiesta, e sono d'accordo con @celtschk che ciò che descrivi è contro ciò che è permesso dal momento che il compilatore deve ignorare i pragma non riconosciuti e la tua descrizione è che non li ignora. – mah

+0

Se il compilatore lo fa per * tutti * i pragma, allora probabilmente li "riconosce". –

3

La versione n3337 dello standard C++ dice

Una direttiva al preprocessore della forma #pragma pp-tokensopt new-line fa sì che l'attuazione a comportarsi in un modo definito dall'implementazione. Il comportamento potrebbe causare errori di traduzione o far sì che il traduttore o il il programma risultante si comportino in modo non conforme. Qualsiasi pragma non riconosciuto dall'implementazione viene ignorato.

Penso che consenta al compilatore di fare quasi tutto ciò che vorrebbe fare in caso di un #pragma. Sia la "traduzione fallita" che "il traduttore o il programma risultante si comportano in modo non conforme" coprono una vasta gamma di opzioni.

Questo, ovviamente, non significa che sia una cosa saggia permettere al compilatore di fare cose "pazze" - potrebbe "turbare" le persone, ma è perfettamente valido dal punto di vista dello standard.

Problemi correlati