96 votes

représentation de piège

  1. Qu'est-ce que la représentation d'un piège en C (quelques exemples pourraient aider)? Est-ce que cela s'applique au C ++?

                   float f=3.5;
                  int *pi = (int*)&f;
     
  2. Edit: Je sais que 'pi' viole la règle de crénelage et qu’il correspond à UB selon la norme C. Au moins sur GCC, il ne produit aucune erreur, mais des avertissements. Dans cette implémentation (c'est-à-dire, GCC), en supposant que sizeof(int) == sizeof(float) %% f et *pi ont la même représentation / modèle binaire? Qu'en est-il de MSVC?

131voto

Zack Points 44583
  1. Un piège de la représentation est un fourre-tout terme utilisé par C99 (IIRC pas en C89) pour décrire les modèles de bits qui s'inscrivent dans l'espace occupé par un type, mais de déclencher un comportement indéfini si elle est utilisée comme une valeur de ce type. La définition est dans la section 6.2.6.1p5 et je ne vais pas citer ici, car il est long et confus. Un type pour lequel de tels modèles de bits existent est dit "avoir" piège des représentations. Tout type (sauf unsigned char) peut avoir piège des représentations, mais pas de type est nécessaire de les avoir. La norme ne parle que de deux piège des représentations: logiciel-visible des bits de parité sur les types numériques, et "négatif zéro" non-deux-compléter les architectures. Autant que je sache, personne n'a fabriqué un CPU qui ne soit de ces choses dans de nombreuses années, et le C de la norme en continuant à fournir en vue de leur éventuelle existence est une sorte de bête. Un meilleur exemple à mon humble avis serait à virgule flottante IEEE de signalisation NaNs, dont le comportement n'est pas défini explicitement par le C99 (annexe F, section 2.1), même si il est précisé en détail dans la norme IEC 60559.

    Il vaut probablement la peine de mentionner que d'un pointeur null est pas un piège de la représentation d'un type de pointeur. Pointeurs Null seulement provoquer un comportement non défini si ils sont déréférencés ou offset, d'autres opérations sur les pointeurs null (plus important encore, les comparaisons et les copies) sont bien définis. Piège des représentations provoquer un comportement non défini si vous ne lisez - le en utilisant le type qui a le piège de la représentation.

  2. Le code vous montrer a un comportement indéfini, mais c'est parce que le pointeur de-aliasing règles, non pas à cause du piège des représentations. C'est la façon de convertir un float dans la int avec la même représentation (en supposant, comme vous le dites, sizeof(float) == sizeof(int))

    int extract_int(float f)
    {
        union { int i; float f; } u;
        u.f = f;
        return u.i;
    }
    

    Ce code a indéterminée (et non pas défini) comportement en C99, qui signifie en gros que la norme ne définit pas ce qu'valeur entière est produit, mais vous n'obtenez pas certaines entier valide, il n'est pas un piège de la représentation, et le compilateur n'est pas autorisé à optimiser sur l'hypothèse que vous ne l'avez pas fait. (Section 6.2.6.1, paragraphe 7. Ma copie de C99 peut inclure des techniques corrigienda - mon souvenir est que ce n' était pas défini dans la publication originale, mais a été changé à précisées dans un TC.)

6voto

Puppy Points 90818

Comportement non défini pour aliaser un float avec un pointeur sur int.

5voto

MSN Points 30386

En général, tous les non-trap IEEE-754 valeur à virgule flottante peut être représentée par un entier sur certaines plates-formes sans aucun problème. Cependant, il y a des valeurs à virgule flottante qui peut entraîner un comportement inattendu si l'on suppose que toutes les valeurs à virgule flottante ont un entier unique de représentation et de vous arriver, à force de la FPU pour charger cette valeur.

(Exemple tiré d' http://www.dmh2000.com/cpp/dswap.shtml)

Par exemple, lorsque vous travaillez avec des FP données dont vous avez besoin pour le maréchal entre les Processeurs avec différents endianness, vous pourriez penser de la manière suivante:

double swap(double)

Malheureusement, si le compilateur charge l'entrée dans une FPU s'inscrire et c'est un piège de la représentation, le FPU peut l'écrire avec un équivalent piège de la représentation qui se trouve être une autre représentation binaire.

En d'autres termes, il y a quelques FP valeurs qui n'ont pas un bit correspondant de la représentation si vous ne vous convertissez pas correctement (par la bonne, je veux dire par le biais d'un union, memcpy par char * ou d'un autre mécanisme standard).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X