Exemple de quelque chose qui est, et n'est pas, une « expression constante » en C?

StackOverflow https://stackoverflow.com/questions/3755524

  •  04-10-2019
  •  | 
  •  

Question

Je suis un peu confus entre ce qui est et n'est pas une expression constante en C, même après beaucoup googleing. Pourriez-vous donner un exemple de quelque chose qui est, et qui n'est pas, une expression constante dans C?

Était-ce utile?

La solution

Une expression constante peut être évaluée au moment de la compilation. Cela signifie qu'il n'a pas de variables en elle. Par exemple:

5 + 7 / 3

est une expression constante. Quelque chose comme:

5 + someNumber / 3

ne sont pas, en supposant someNumber est une variable (c.-à-pas lui-même une constante de temps de compilation).

Autres conseils

Il y a une autre subtilité à des expressions constantes. Il y a des choses qui sont connues pour le compilateur, mais ne peuvent pas être connues du préprocesseur.

Par exemple (24*60*60) peut être calculé par les deux, mais sizeof struct foo est seulement connue du compilateur. Cette distinction peut importe si vous essayez de vérifier qu'un struct est défini pour répondre à une taille mandatée à l'extérieur, ou que ses membres sont mis en correspondance à l'extérieur des compensations spécifiées. (Ce cas d'utilisation se pose souvent lorsque les pilotes de périphériques de codage où le struct décrit les registres de l'appareil comme dans l'espace layed mémoire.)

Dans ce cas vous ne pouvez pas dire simplement #if (sizeof(struct UART) == 12) parce que le préprocesseur fonctionne à une passe en avant de la compilation et peut tout simplement pas connaître la taille de tous les types. Il est, toutefois, une expression constante et serait valable comme un initialiseur pour une variable globale (par exemple int UARTwords = sizeof(struct UART) / sizeof(short);), ou de déclarer la taille d'un tableau (par exemple unsigned char UARTmirror[sizeof(struct UART)];)

Personne ne semble avoir mentionné un autre type d'expression constante: constantes adresse. L'adresse d'un objet avec une durée de stockage statique est une constante d'adresse, vous pouvez donc faire ce genre de chose à la portée du fichier:

char x;
char *p = &x;

littéraux de chaîne définir des tableaux avec la durée de stockage statique, cette règle est aussi pourquoi vous pouvez le faire à la portée du fichier:

char *s = "foobar";

Tout littéral à valeur unique est une expression constante.

3     0.0f    '\n'

(String littéraux sont bizarres, parce qu'ils sont en fait des tableaux. Semble "hello" est pas vraiment une constante, car il finit par avoir à relier et tout cela, et l'adresse et le contenu peut changer à l'exécution.)

La plupart des opérateurs (sizeof, moulages, etc.) appliquées aux constantes ou types sont des expressions constantes.

sizeof(char)
(byte) 15

Toute expression impliquant seulement des expressions constantes lui-même est aussi une expression constante.

15 + 3
0.0f + 0.0f
sizeof(char)

Toute expression impliquant des appels de fonction ou des expressions non constantes est généralement pas une expression constante.

strlen("hello")
fifteen + x

statut de toute macro comme une expression constante dépend de ce qu'il se développe pour.

/* 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)

J'ai eu à l'origine des choses ici sur les identifiants de const, mais je teste cela et apparemment il ne s'applique pas dans C. const, assez curieusement, ne déclare pas constantes (au moins, pas assez les « constantes » pour être utilisé dans les déclarations de switch). Cependant, il ne en C ++,.

Une autre petite ride amusant: en C, la valeur d'un « ENUM » est une constante, mais ne peut être utilisé après la déclaration du « ENUM » est terminée. Ce qui suit, par exemple, ne sont pas acceptables dans la norme C, mais il est acceptable en C ++:

enum {foo=19, bar, boz=bar+5;};

Il pourrait être réécrite:

enum {foo=19, bar}; enum {boz=bar+5;};

bien que cela finirait par définir plusieurs types d'énumération différents, plutôt que celui qui détient toutes les valeurs.

Aussi integral character constants que 'a' ou '\n' sont des constantes que le compilateur reconnaît en tant que tel. Ils ont le type int.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top