8
votes

offset de la compilation

Y a-t-il un moyen de trouver le décalage d'un membre d'une structure à la compilation? Je souhaite créer une constante contenant le décalage d'un membre de la structure. Dans le code suivant, le offsetof () code> macro fonctionne dans le premier PRINTF code> Déclaration. Cependant, l'utilisation dans la ligne 10 pour déclarer of code> génère l'erreur:

"Impossible de résoudre" -> "opérateur comme une expression constante". p> BlockQuote>

Y a-t-il une autre façon de le faire? P>

struct MyStruct
{
   unsigned long lw;
   unsigned char c[5];
   int i;
   int j;
   unsigned long last;
};

const int ofs = offsetof(struct MyStruct, i);  // This line in error

int main(void)
{
   printf("Offset of c = %d.\n", offsetof(struct MyStruct, c) );
   printf("Offset of i = %d.\n", ofs );
   return 0;
}


0 commentaires

3 Réponses :


4
votes

Il compile sans avertissement ici avec g ++ 4, après avoir ajouté le bon #Inclus.

Êtes-vous #Commluant STDDEF.H? offsetof () est une macro, pas un mot clé intégré en c.

Si cela ne le répare pas, essayez de faire la constante statique, de la confiner au module. Cela pourrait rendre le compilateur heureux.


0 commentaires

10
votes

La compensation de () macro est une construction de compilation. Il n'y a pas de moyen standard conforme de le définir, mais chaque compilateur doit avoir une bonne façon de le faire.

Un exemple serait: xxx

tout en cas de compilation -time construire techniquement (voir commentaires par utilisateur "litb"), chaque compilateur doit avoir au moins un une telle expression qu'il est capable de résoudre au moment de la compilation, ce qui est exactement ce que offsetof () est défini dans .

Il y a probablement une autre erreur de votre code - une inclusion manquante de ou d'autres autre chose irritant de votre compilateur.


7 commentaires

Ce n'est pas ce qu'il veut dire avec "la compilation", bien sûr. Vous montrez une construction qui n'utilise pas une fonction de bibliothèque, mais cela ne signifie pas qu'il n'évalue à une valeur de temps de compilation. Le Code est effectivement émis ou non est hors de propos du parcours - le projet C: «Une expression constante arithmétique doit avoir un type arithmétique et disposer d'opérandes uniquement des constantes entier, des constantes de conserve, des constantes de dénombrement, des constantes de caractère et des expressions de caractère». Les pointeurs ne sont pas autorisés dans le mélange.


Offsetof est une construction d'heure de compilation et évalue une expression constante entier, mais votre exemple de mise en œuvre ne le fait pas.


Il y a non Way dans la langue pour définir offset de () comme quelque chose qui évalue une expression constante entière. Il y a non moyen de le définir sans utiliser des pointeurs. Peu importe ce que vous faites, vous allez toujours compiler sur un compilateur intégré et / ou la capacité du compilateur à optimiser votre expression de manière appropriée. Vérifiez Wikipedia sur offsetof ou toute bibliothèque C Open-Source C. Ainsi, alors que vous êtes techniquement correct sur la définition des expressions constantes entière (et j'adapte mon libellé), vous vous méprenez-vous en pointant un doigt à mon exemple de mise en œuvre.


Pour ce que cela vaut, la mise en œuvre ci-dessus est identique à celle de (GLIBC) ./resolv/nss_dns/dns-network.c.


J'ai signalé mon doigt non seulement à votre exemple de mise en œuvre, mais votre exemple de mise en œuvre avec votre "voir, tout le temps de compilation" attaché à celui-ci. Je suis conscient qu'il peut y avoir des implémentations défectueuses de cette macro (et le questionneur vient probablement de frapper une telle mise en œuvre défectueuse). Je ne peux pas commenter sur cette macro C-Files, mais si elle utilise une telle chose et que cela prétend être un remplacement portable de "offset de" (je doute - parce que le fichier a l'air "officiel"), alors c'est juste faux - mais ça Peut toujours travailler pour Son but . La mise en œuvre de GCC, par exemple, appelle simplement "__builtin_offsetof".


Cela dit, je vais supprimer mon -1 parce que vous avez manipé l'incohérence. En tout cas, je ne veux pas lire Wikipedia - il y a suffisamment de non-sens écrit sur C et C ++ sur celui-ci - je ne suis pas prêt à devenir infecté :)


Juste pour le signaler à nouveau: il y a NO moyen de mettre en œuvre offset d'une manière portable . C'est un coin difficile de la norme linguistique.



3
votes

Si vous avez un #include comme je suppose (le message d'erreur que vous citez sans signifierait de sens), il s'agit d'un bogue dans votre compilateur. offsetof résultat est une expression constante entier en C99 ainsi que dans C90.


0 commentaires