Sono un po 'confuso tra ciò che è e non è una costante espressione in C, anche dopo molto Googleing. Potresti fornire un esempio di qualcosa che è, e che non è, un'espressione costante in C?Esempio di qualcosa che è, e non è, una "Espressione costante" in C?
risposta
Un'espressione costante può essere valutata in fase di compilazione. Ciò significa che non ha variabili in esso. Ad esempio:
5 + 7/3
è un'espressione costante. Qualcosa di simile:
5 + someNumber/3
non è, supponendo someNumber
è una variabile (cioè, non di per sé una fase di compilazione costante).
C'è un'altra sottigliezza nelle espressioni costanti. Ci sono alcune cose che sono note al compilatore, ma non possono essere conosciute dal preprocessore.
Ad esempio (24*60*60)
può essere calcolato da entrambi, ma sizeof struct foo
è noto solo al compilatore. Questa distinzione può essere importante se si sta tentando di verificare che uno struct
sia definito per soddisfare una dimensione con obbligo esterno o che i suoi membri siano associati a offset specificati esternamente. (Questo caso di utilizzo spesso sorge quando codifica i driver di periferica in cui la struct
descrive dispositivo registra come spiegate nello spazio di memoria.)
In quel caso non si può semplicemente dire #if (sizeof(struct UART) == 12)
perché il preprocessore funziona a un passaggio davanti alla compilazione e semplicemente non può conoscere la dimensione di qualsiasi tipo. È, tuttavia, un'espressione costante e sarebbe valida come inizializzazione di una variabile globale (ad esempio int UARTwords = sizeof(struct UART)/sizeof(short);
), o di dichiarare la dimensione di un array (ad esempio unsigned char UARTmirror[sizeof(struct UART)];
)
+1, quelli che il preprocessore non può gestire sono chiamati 'espressioni costanti limitate', credo. –
@Carl: bello sapere, grazie. Le "espressioni costanti ristrette" sono definite in qualche riferimento? Non lo trovo nello standard C11. – Tim
Ciao @Tim, non ho una specifica a portata di mano, ma Microsoft ha qualcosa qui: https://docs.microsoft.com/en-ca/cpp/c-language/c-constant-expressions –
Qualunque singolo valore letterale è un'espressione costante.
3 0.0f '\n'
(stringhe letterali sono strani, perché sono in realtà gli array. Sembra "hello"
in realtà non è una costante, in quanto finisce per dover essere collegati e tutto ciò che, e l'indirizzo e il contenuto può cambiare in fase di esecuzione .)
La maggior parte degli operatori (sizeof, cast, ecc.) Applicati a costanti o tipi sono espressioni costanti.
Qualsiasi espressione che coinvolge solo espressioni costanti è anch'essa un'espressione costante.
15 + 3
0.0f + 0.0f
sizeof(char)
Qualsiasi espressione contenente chiamate di funzione o espressioni non costanti è solitamente non un'espressione costante.
strlen("hello")
fifteen + x
Lo stato di qualsiasi macro come espressione costante dipende da cosa si espande.
/* Always a constant */
#define FIFTEEN 15
/* Only constant if (x) is
#define htons(x) ((((x) >> 8) | ((x) << 8)) & 0xffff)
/* Never constant */
#define X_LENGTH strlen(x)
Inizialmente avevo alcune cose in qui circa const
identificatori, ma ho provato che e apparentemente non si applica in C. const
, stranamente, non dichiarare le costanti (almeno, non quelli "costante "sufficiente per essere utilizzato nelle istruzioni switch
). In C++, tuttavia, lo fa.
Nota che sizeof () è * sempre * un'espressione costante, anche se l'argomento è un'espressione non const, poiché è il * tipo * sull'espressione che è l'argomento, non l'espressione stessa. – Clifford
@Clifford: in 'C99', sizeof applicato a un VLA non specifica una costante" 6.5.3.4 ... Se il tipo dell'operando è un tipo di array di lunghezza variabile, l'operando viene valutato, altrimenti l'operando non è valutato e il risultato è una costante intera. " – pmg
@cHao: 'const' è un qualificatore di tipo. Si applica agli oggetti ... e nessun oggetto può essere una costante. – pmg
Un'altra ruga divertente: in C, il valore di un 'enum' è una costante, ma può essere utilizzato solo dopo che la dichiarazione dell '"enum" è completa. Di seguito, per esempio, non è accettabile in serie C, anche se è accettabile in C++:
enum {foo=19, bar, boz=bar+5;};
Potrebbe essere riscritta:
enum {foo=19, bar}; enum {boz=bar+5;};
se questo finirebbe definire più tipi di enumerazione diversi, piuttosto che uno che contiene tutti i valori.
Giusto per dire che queste costanti 'enum' hanno tipo' int'. –
Anche integral character constants
come 'a'
o '\n'
sono costanti che il compilatore riconosce come tali. Hanno tipo int
.
Nessuno sembra aver menzionato ancora un altro tipo di espressione costante: costanti di indirizzo. L'indirizzo di un oggetto con la durata di archiviazione statica è una costante indirizzo, quindi si può fare questo genere di cose nell'ambito di file:
char x;
char *p = &x;
stringhe letterali definiscono le matrici con la durata di archiviazione statica, quindi questa regola è anche il motivo per cui si può fare questo per lo scopo del file:
char *s = "foobar";
+1, ma è opportuno notare che questo tipo di espressione costante di solito non è ** una costante effettiva in fase di compilazione, e forse non al momento del collegamento se si utilizza il collegamento dinamico. Nella maggior parte delle implementazioni del mondo reale, risulta in una * ricollocazione *. –
Questo è quello che stavo cercando! – abhiarora
- 1. espressione non valutata a una costante- C++
- 2. espressione non è una costante intergrale clang libC++ threading
- 3. C4127: espressione condizionale è costante
- 4. elemento Initializer non è costante in C
- 5. __builtin_round non è un'espressione costante
- 6. non è una costante in Enum
- 7. Ricezione 'espressione viene assegnato deve essere costante' quando è
- 8. Perché non è possibile in C inizializzare una costante con un'altra costante?
- 9. perché una variabile di constexpr non inizializzata non è costante?
- 10. costante parametro stringa espressione in funzione 11 constexpr C++
- 11. espressione è sempre vero in C#
- 12. È costante fusione con la pratica comune Mercurial? Qualcosa non va con questo flusso di lavoro?
- 13. Controlla se qualcosa non è in una lista in Python
- 14. F # attributi, typeof, e "Questa non è un'espressione costante"
- 15. Perché questo codice non è spazio costante?
- 16. È possibile memorizzare espressione lambda nell'array C#
- 17. Come il ritorno di stringa non è una costante
- 18. espressione metodo non è di tipo Funzione
- 19. Espressione di una stringa C# LINQ espressione
- 20. * qualcosa * if * espressione * sintassi in JavaScript (FF)
- 21. Una funzione è un esempio di incapsulamento?
- 22. Come nascondere qualcosa che è già stato stampato in Python
- 23. Restituisce qualcosa che è allocato nello stack
- 24. Come scrivere un matcher che non è uguale a qualcosa
- 25. Non è richiesta una funzione constexpr per restituire un'espressione costante?
- 26. È possibile che una ruggine costante/statica sia esposta a C?
- 27. Creazione di una libreria const-correct (C++) che si basa su una libreria non costante alla costante
- 28. C# è per Visual Studio come PHP è per ... qualcosa?
- 29. Come dovrei definire qualcosa di costante come in Erlang
- 30. C++: Perché questo constexpr non è una costante di tempo di compilazione
Grazie mille Carl, estremamente utile! :) –
L'* indirizzo * di alcune variabili può essere in un'espressione costante, sebbene (quelle con durata di memorizzazione statica). – caf