Je veux spécifier une taille d'énumération de 64 bits pour une énumération. Comment est-ce possible via GCC? Le code n'a pas besoin d'être «portable» en ce que je ne suis intéressé que de faire fonctionner le code sur la compilation de GCC pour X86-32 et X86-64 Linux. Cela signifie que tout piratage pouvant fournir la fonctionnalité que je veux va bien tant que cela fonctionne pour ces cibles.
donné à ce code: p> Ceci imprime actuellement 4, Alors que je veux pouvoir forcer la taille à être 8. Tentative de spécifier des valeurs dans l'affectation enum plus de 4 octets entraînant un avertissement. Par exemple, p> produirait: p> un Réponse à une question similaire ici ne semble pas donner de bons résultats. C'est-à-dire que le même avertissement est produit à la suite de: p> Remarque: l'avertissement de plusieurs caractères peut être éteint en compilant avec Since Les gens sont intéressés pourquoi je fais cela, j'ai écrit un moteur de désassembleur. Je reçois chaque partie d'une instruction comme une chaîne. Je veux donc que l'énumération ressemble à ceci: p> Je peux ensuite stocker facilement des informations sémantiques avec un code comme celui-ci: P> -wno-multichar .
if(strcmp(example_insn, "mov") == 0) {
insn = mov;
} else if(strcmp(example_insn, "cmp") == 0) {
insn = cmp;
} ...
9 Réponses :
Vous pouvez utiliser un Union code> type:
perhas que vous pouvez utiliser définit des définitions?
enum { garbage1, garbage2, sentinel = 12345L }
#define code> est mon dernier recours. Je préférerais une énumération. Votre suggestion d'énumération n'est pas tout à fait ce que je veux. J'en ai besoin pour représenter une chaîne.
Bien que la norme C99 sur x86 i get p> et sur x64 (sur ma machine), je reçois p> bien que , demandant un respect pédant de la norme, je reçois, comme prévu: p> En fait, c'est un peu plus compliqué; ¶4 Spécifie que la mise en œuvre est libre de choisir comme "Type de base" tout type particulier "compatible avec D'autre part, ¶2 Spécifie que chaque membre du grâce à @ jons34yp pour indiquer mon erreur initiale. P> p> spécifie qu'un énorme ne puisse être basé sur quoi que ce soit un int code> (§6.7.2.2 ¶2) s> 1 sup >, il semble que
gcc code> suit l'idée C ++ que, si une valeur dans un
Enum code> est plus grosse qu'un
int code>, il peut la baser sur un plus grand type entier. Je n'ai aucun problème avec ce code, ni sur x86 ni sur x64:
char code>, type d'entiers signé ou un type d'entier non signé", tant qu'il peut représenter Tous les éléments du
Enum code>. p>
Enum code> doit être représentable comme
int code>, même si la mise en œuvre est libre de baser votre < Code> Enum Code> Même sur un bit Gazillion Bit Entier, les constantes définies pour cela ne peuvent pas être quelque chose qui ne peut être représenté par un
int code>. Ainsi, cela signifie que dans la pratique em> le compilateur ne basant pas le
enum code> sur quelque chose de plus grand qu'un
int code>, mais il peut < / em> base sur quelque chose de plus petit si vos valeurs ne nécessitent pas la gamme complète de
int code>. p>
li>
ol>
Malgré cet avertissement, cette solution est-elle garantie de fonctionner comme prévu avec mes plates-formes cible? En outre, est-il possible d'adapter cela au style littéral à la chaîne / à plusieurs caractères que je veux? Je suppose que je pourrais toujours générer ces chiffres, mais c'est moins lisible.
@Mikekwan: Cet avertissement apparaît uniquement si vous demandez explicitement la conformité standard de Pedantic ( -ansi -peantique code>), en ce qui concerne
gcc code> ne contient aucun problème à fonder le
Enum code> S sur les types plus gros que
int code> si nécessaire (comme vous pouvez le voir, je l'ai testé sur X86 et X64 et ça marche bien). En ce qui concerne les littéraux multi-charmes, j'essaie de regarder s'il y a un moyen de les faire travailler.
Si vous souhaitez spécifiquement des énumes 64 bits, vous pouvez le faire: Enum quelque_eum {/ * ... * / max = 0x7FFFFFFFFFFFFFFFF}; code>. Avoir un membre de cette valeur garantit que le type nécessite (au moins) 64 bits (ou que le compilateur le rejetera).
@KeithThompson: 0x7FFFFFFFFFFFFFFLL code>, je pense. En ce qui concerne le problème des littéraux multicharacter, je pense qu'il n'y a pas de solution.
@Matteoitalia: le suffixe ll code> n'est pas nécessaire; Une constante hexagonale est d'un type assez grand pour tenir sa valeur. Et je pense que vous avez raison de ne pas avoir de solution pour les littéraux multi-micracters - autres que ne les utilisant pas (voir ma réponse).
@Matteoitalia. Votre réponse est fausse. §6.7.2.2 ¶2 Ne parle que sur les constantes de dénombrement (le bit A = 12345 code>), § 6.7.2.2 ¶4 dit "Chaque type énuméré <...>. Le choix de Type est défini par la mise en œuvre, " i>
@ JONS34YP: Vous avez raison, je corrigerai la réponse; Néanmoins, étant donné que chaque valeur du Enum code> ne peut pas être supérieure à un
int code> (en raison de ¶2), il ne serait pas logique de le rendre plus grand que
INT code>.
Vous avez mal interprété l'avertissement, ce qu'il dit que les littéraux de caractères sont toujours de type int code>, jamais de type
long code> ou
long long code > Assurez-vous d'utiliser les numéros de décalage correct. p> p>
C'est une belle solution. Je vais essayer plus tard. Savez-vous si cela peut être converti en macro en quelque sorte?
Cette solution fonctionne parfaitement. Je vais accepter cette réponse et faire une nouvelle écriture démontrant comment l'utiliser.
Comme la réponse de Matteo Italia dit, GCC vous permet de définir un type d'énumération de 64 bits en spécifiant une valeur de 64 bits pour l'un des membres. Par exemple: comme pour votre utilisation de Ce dernier est Legal (et soutenu par GCC), mais la valeur est définie par la mise en œuvre. La norme indique que le type est toujours Par exemple, ce programme: P> 'mov' code>,
'CMP' code>, etc., il n'y a pas de corrélation nécessaire entre la représentation d'un littéral de chaîne comme
"mov" code> et la représentation d'une constante de caractère multi-caractères similaire à
'mov' code>. p>
int code> et GCC ne semble pas avoir une extension qui vous permet de remplacer cela. Donc, si
int code> est 4 octets, puis
'sysenter' code>, s'il est accepté du tout, il n'a pas nécessairement la valeur que vous recherchez. GCC semble ignorer tous mais les octets à faible commande d'une telle constante. La valeur de la constante semble être cohérente à travers les systèmes Big-Endian et Little-Endian - ce qui signifie qu'il ne sera pas em> correspond toujours à la représentation d'un littéral de chaîne similaire. P>
'abcd' = 0x61626364
'abcdefgh' = 0x65666768
*(unsigned*)s1 = 0x61626364
*(unsigned*)s2 = 0x61626364
En ce qui concerne que cela puisse être fait avec une hache plus rapide, je ne crois vraiment pas. J'utilise la haquetable du noyau Linux en ce moment. Cela prend une clé et une taille d'une clé. Cela signifie donc que je devrais réellement faire le rembourrage que je fais actuellement de toute façon. La raison en est que je suis en fait simplifié la justification - les cordes générées de libopcodes que j'utilise pour démonter avoir des caractères spatiaux de rembourrage qui doit être dépouillé. L'utilisation d'une hache utiliserait exactement la même quantité de calcul mais ajoutez également le coût du calcul du hachage et d'ajouter à la haquetable.
Après une enquête, je conviens que le problème réel est qu'un littéral multicapare ne peut être que 4 octets (au moins moins de X86-32 et X86-64). Je ne trouve pas de citation pour cela, cependant. La solution par Johansson fonctionne bien à la place.
Votre meilleur pari est probablement à l'aide du système de construction pour générer automatiquement un ensemble de définition. De cette façon, vous obtiendrez également ladimité droite.
Un exemple de programme GEN-INSTRUCTION CODE> pourrait ressembler à ce p>
instructions.h : instructions.list gen-instructions
./gen-instructions `cat $<` > $@
par johansson frappe le clou sur la tête avec sa réponse ICI . Comme exemple concret de la manière d'utiliser cette technique, j'ai écrit ce programme ( Ceci peut être compilé avec le exécuté avec insn_enum.c code>):
suivant Makefile code>: p>
./ insn_enum_32 && ./insn_enum_64 code> imprimera: p>
gcc -std=gnu99 -m32 -pedantic -Wall insn_enum.c -o insn_enum_32
insn_enum.c:13:13: warning: ISO C restricts enumerator values to range of âintâ
gcc -std=gnu99 -m64 -pedantic -Wall insn_enum.c -o insn_enum_64
insn_enum.c:13:13: warning: ISO C restricts enumerator values to range of âintâ
Juste pour répondre à la question initiale dans le titre - C ++ 11 vous permet de spécifier le type d'énorme, et donc sa taille:
enum class mynamedenum : long { FOO, BAR }
Il n'y a pas de moyen officiel de spécifier Enum Strong> Taille. Peut-être pas 100% appliqué à votre cas, mais avec ce piratage, vous pourriez obtenir une taille d'énumération ciblée pour être multiplate-forme. Vous devez utiliser le mot-clé Jetez un coup d'œil sur l'exemple ci-dessous: P> __ attribut __ code> avec le paramètre
Emballé code> pour réduire la taille enum jusqu'à la valeur maximale de la liste Enum.
Sizeof en_8b_t: 8
Sizeof en_4b_t: 4
Sizeof en_2b_t: 2
Sizeof en_1b_t: 1
Default enum size is: 4
C'est une bonne suggestion bien que cela ne fonctionne que pour le compilateur GCC.
Oui, la question a été posée pour GCC. Les attributs sont spécifiques pour différents compilateurs.
Pourquoi voudriez-vous faire cela? On dirait que vous n'utilisez pas
Enum code> d'une manière "propre".
Qu'est-ce que sur la terre '12345' représenterait? Un seul caractère contenant 5 caractères? Si vous souhaitez stocker une valeur numérique, écrivez-le sans
' code> - Je ne reçois pas d'avertissements avec
GCC code> sur x64.
JFTR,
'ABC' code> est une extension MSVC non standard pour
'A' << (U * Char_bit) | 'B' << (V * CHAR_BIT) | 'C' << (W * Char_bit) ... Code> Avec la cartographie définie par la mise en œuvre entre U, V, W, ... et l'ensemble de nombres réels.
@DANFEGO: J'ai ajouté une justification.
@Matteoitalia: Je veux stocker la représentation numérique d'une chaîne comme uint64_t. Regardez la justification.
@Mikekwan: Ensuite, votre problème n'est pas avec
Enum code> S, mais avec chaîne
uint64_t code> littéraux.
'12345' code> est en fait une caractéristique standard de la langue. La valeur est définie par la mise en œuvre (ce qui signifie qu'il est à peu près inutile pour le code portable).
@KeithThompson: Désolé, je ne connaissais pas les littéraux multi-micracter, c'est la première fois que je chante sur eux.
Mais toutes les constantes de caractères sont de type
int code>, et je ne pense pas que GCC a une extension pouvant remplacer cela.
Édité pour corriger
null code> (qui est un null pointeur i> constant) à "caractères nuls".