La définition de const valeurs dans C
J'ai un projet C où tout le code est organisé en *.c
/*.h
paires de fichier, et j'ai besoin de définir une constante de valeur dans un fichier, qui sera toutefois également être utilisé dans d'autres fichiers. Comment dois-je déclarer et définir cette valeur?
Devrait-il être comme static const ...
dans le *.h
fichier? Comme extern const ...
dans le *.h
fichier et définis dans le *.c
fichier? En quoi importe-t-il si la valeur n'est pas une primitive de type de données (int
, double
, etc), mais un char *
ou un struct
? (Même si dans mon cas c'est un double
.)
La définition des trucs à l'intérieur *.h
fichiers ne semble pas être une bonne idée en général; on doit déclarer les choses dans le *.h
fichier, mais les définir dans le *.c
fichier. Cependant, la extern const ...
approche semble inefficace, car le compilateur ne serait pas en mesure de l'inclure la valeur, au lieu d'avoir à être accessible via son adresse de tous les temps.
Je suppose que l'essence de cette question est: Doit-on définir static const ...
valeurs dans *.h
des fichiers dans C, dans le but de les utiliser plus qu'un seul endroit?
OriginalL'auteur Paggas | 2008-12-10
Vous devez vous connecter pour publier un commentaire.
La règle que j'ai suivi est à seulement déclarer les choses dans les H des fichiers et de les définir en C fichiers. Vous pouvez déclarer et définir en un seul fichier C, en supposant qu'il ne sera utilisée dans ce fichier.
Par déclaration, je veux dire en informer le compilateur de son existence, mais ne pas allouer de l'espace pour cela. Cela comprend
#define
,typedef
,extern int x
, et ainsi de suite.Définitions affecter des valeurs à des déclarations et des allouer de l'espace pour eux, comme
int x
etconst int x
. Cela comprend des définitions de fonction; y compris les en-tête des fichiers fréquemment mener à du gaspillage de l'espace du code.J'ai vu trop de jeunes programmeurs obtenir confus quand ils ont mis
const int x = 7;
dans un fichier d'en-tête et se demandent ensuite pourquoi ils obtiennent une erreur de lien pourx
être définie plus d'une fois. Je pense à un strict minimum, vous avez besoin destatic const int x
afin d'éviter ce problème.Je ne serais pas trop inquiet au sujet de la vitesse de la code. Le principal problème avec les ordinateurs (en termes de vitesse et de coût) il y a longtemps déplacé de la vitesse d'exécution de la facilité de développement.
OriginalL'auteur paxdiablo
Si vous avez besoin de constantes (réel, de compiler des constantes de temps), vous pouvez le faire de trois façons, les mettre dans des fichiers d'en-tête (il n'y a rien de mal à cela):
En C++, j'ai tendance à utiliser l'enum façon, car elle peut être portée dans un espace de noms. Pour le C, j'utilise la macro. Cette basicially est une question de goût bien que. Si vous avez besoin de virgule flottante constantes, vous ne pouvez pas utiliser l'énumération plus. En C++, j'utilise la dernière manière, le static const double, dans ce cas (note en C++ statique serait redondant; ils deviennent statiques automatiquement depuis qu'ils sont const). En C, je voudrais garder le à l'aide des macros.
C'est un mythe que l'utilisation de la troisième méthode va ralentir votre programme en aucune façon. Je préfère juste l'énumération puisque les valeurs que vous obtenez sont des rvalues - vous ne pouvez pas obtenir leur adresse, que je considère comme une sécurité supplémentaire. En outre, il ya beaucoup moins de la chaudière-plaque de code écrit. L'œil est concentrée sur les constantes.
OriginalL'auteur Johannes Schaub - litb
Avez-vous vraiment besoin de s'inquiéter au sujet de l'avantage de inline? Sauf si vous écrivez du code incorporé, un bâton à la lisibilité. Si c'est vraiment un nombre magique de quelque chose, j'aimerais utiliser une définition; je pense const est mieux pour des choses comme const chaînes de version et la modification de la fonction des arguments d'appel. Cela dit, la définir .c, déclarer .h la règle est certainement assez universellement acceptés de la convention, et je ne voudrais pas casser juste parce que vous pourrait enregistrer un mémoire de recherche.
OriginalL'auteur Mikeage
En règle générale, vous ne définissent pas les choses comme
static
dans un en-tête. Si vous ne définissezstatic
variables dans un en-tête de chaque fichier qui utilise l'en-tête obtient sa propre copie privée de tout ce qui est déclaréstatic
, qui est l'antithèse de SEC principe: ne vous répétez pas.Donc, vous devez utiliser une solution de rechange. Pour les types integer, à l'aide enum (défini dans l'en-tête) est très puissant, il fonctionne bien avec les débogueurs trop (bien que les meilleurs débogueurs peut être en mesure d'aider avec
#define
macro valeurs trop). Pour les non-types d'entiers, unextern
déclaration (éventuellement qualifié avecconst
) dans l'en-tête et une seule définition dans un fichier C est généralement la meilleure façon d'aller.clairement, vous avez une vue différente de la situation. Toutefois, si vos en-têtes de définir des objets statiques, il est peu probable que mon code va les utiliser. Il y a des exceptions, mais ce sont des exceptions.
OriginalL'auteur Jonathan Leffler
J'aimerais voir plus de contexte de votre question. Le type de la valeur critique, mais vous l'avez laissée. Le sens du mot-clé const en C est assez subtile, par exemple
const char *p;
ne signifie pas que le pointeur p est une constante; vous pouvez écrire p tout ce que vous voulez. Ce que vous ne pouvez pas écrire, c'est le souvenir que p points, et cela reste vrai même que les p de changement de valeur. C'est à peu près le seul cas où j'ai vraiment à comprendre; en général, le sens de l'subtil placement de const m'échappe. Mais ce cas particulier est extrêmement utile pour les paramètres de la fonction parce que c'extraits d'une promesse de la fonction de la mémoire de l'argument de points ne sera pas muté.
Il y a un autre cas spécial, tout le monde devrait savoir: les entiers. Presque toujours, une constante nommée entiers doivent être définies dans un .h fichier énumération des littéraux. les types enum non seulement vous permettre de groupe des constantes liées ensemble de manière naturelle, mais aussi de vous permettre de vous les noms de ces constantes pour être vu dans le débogueur, qui est un énorme avantage.
J'ai écrit des dizaines de milliers de lignes de C; probablement des centaines, si j'essaie de le retrouver. (wc ~/src/c/*.c dit de 85 mille, mais certains de qui est généré, et bien sûr, il y a beaucoup de code C qui rôde, d'ailleurs). Hormis les deux cas, je n'ai jamais trouvé une grande utilité pour les const. Je serais heureux d'en apprendre une nouvelle, utile exemple.
OriginalL'auteur Norman Ramsey
Je peux vous donner une réponse indirecte. En C++ (par opposition à C)
const
impliquestatic
. Qui est-à-dire en C++static const
est la même chose queconst
. De sorte que vous indique que les normes C++ corps se sent à propos de la question c'est à dire tousconst
s doit être statique.OriginalL'auteur AlfaZulu
pour autoconf de l'environnement:
Vous pouvez toujours définir des constantes dans le fichier de configuration. AC_DEFINE() je suppose que c'est la macro pour définir à travers l'ensemble de la construction.
OriginalL'auteur FL4SOF
De répondre à l'essentiel de votre question:
Généralement, vous n'avez PAS souhaitez définir une variable statique dans un fichier d'en-tête.
Ce serait la cause que vous avez dupliqué variables dans chacune des unités de traduction (C fichiers) qui incluent l'en-tête.
variables dans un en-tête devrait vraiment être déclaré extern puisque c'est l'implicite de la visibilité.
Voir cette question pour une bonne explication.
En fait, la situation pourrait ne pas être si terrible, que le compilateur aurait probablement convertir un const type d'une valeur littérale. Mais vous ne pourriez pas besoin de s'appuyer sur ce comportement, surtout si des optimisations sont éteints.
OriginalL'auteur Benoit
En C++, vous devez toujours utiliser
pour les constantes et jamais
Définit presque toujours revenir et vous mordre plus tard. Consts sont dans la langue, et sont fortement typé, donc vous n'aurez pas des erreurs étranges à cause de certains secrets de l'interaction. Je mettrais la const dans le fichier d'en-tête. Tant que c'est #pragma once (ou #ifndef x /#define x /#endif), vous n'aurez pas toujours faire des erreurs de compilation.
À la vanille C, vous risquez d'avoir des problèmes de compatibilité lorsque vous devez utiliser #définit.
const
ne fonctionne pas commecase
étiquette, taille de la matrice, ou pour créer un nouveauconst
(const int SEC_PER_MIN = 60; const int SEC_PER_HOUR = SEC_PER_MIN * 60;
ne fonctionne pas). Voir le fantastique liste à puce de Leffler là: stackoverflow.com/questions/1674032/static-const-vs-define-in-cJe suis habitué à c++. J'ai modifié ma réponse à le préciser, car la plupart des gens en se référant à c, utiliser des compilateurs c++ pour compiler.
vraiment? J'ai l'habitude d'utiliser un compilateur C lors de l'utilisation de C, et un compilateur C++ lors de l'utilisation de C++. <la hausse les épaules>
Vous devez utiliser const statique vraiment.. sinon si c'est un objet de nombreuses instances seront créées dans chaque utilisation.
OriginalL'auteur FryGuy
Si vous voulez inline de la valeur de vos fonctions, vous devez utiliser
#define MY_MAGIC_NUMBER 0x12345678
Même un
static const unsigned MY_MAGIC_NUMBER = 0x12345678
va provoquer une valeur d'extraction à partir d'une adresse. Les performances ne seront pas vraiment d'importance sauf si vous la valeur d'un lot de boucles.Je n'utilise que des
const
pour les arguments des fonctions.Il y avait quelques commentaires et votes contre à propos de cette réponse alors j'ai testé mon hypothèse, et vu l'assembly généré et cette réponse est fausse. Fondamentalement
#define
etconst
donnent le même résultat.Const est autant un indice pour le compilateur que c'est pour le programmeur, et le compilateur, lors de l'optimisation, de tirer pleinement parti de cet indicateur. J'en doute fort ne fait aucune différence si c'est un const ou d'un définir dans le cas général.
Aussi, plus les compilateurs modernes permettra de traiter static const int de façon très similaire à un littéral entier dans le code si vous ne prenez jamais l'adresse de la constante.
OriginalL'auteur Gerhard