Il suffit de lire sur un thread de l'université interne: donc de cette façon, tous Je sais que ce problème est plus théorique que pratique (un programmeur à saké ne veut pas modifier la représentation interne d'un EDIT: P> Trois choses: P> S'il vous plaît donner une réponse aux deux questions que j'ai posées si possible. Je suis également intéressé par les réponses aux deuxièmes questions, car dans mon opinion honnête, dans des systèmes intégrés (qui pourraient être des systèmes de 8 bits), cela pourrait être un vrai problème (ou non). P> LI>
nouvelle question: est-ce vraiment em> comportement non défini? Si oui, pourquoi? Sinon, pourquoi? Il n'y a aucune hypothèse sur les opérateurs de comparaison booléenne dans les spécifications? P> li>
ol> p> a code>,
b code> et
wb code> sont Tous déclaré comme
bool code>.
A code> est attribué
1 code>,
b code> est attribué
2 code> et la représentation interne de
wb code > est modifié en
2 code> (en utilisant un
union code>). p>
a code>,
B < / code> et
wb code> sera
true code>, mais
a code> et
wb code> ne sera pas égal, donc cela pourrait donc signifie que l'univers est cassé (
vrai! = true code>) p>
bool code>), mais voici les questions suivantes: p>
bool code> et
int code> ont des tailles différentes, c'est bon. Mais si j'utilise si j'utilise
char code> au lieu de
int code>. Ou lorsque
tailleOf (bool) == taille de (int) code>? P> li>
8 Réponses :
hmm étrange, je reçois une sortie différente de CodePad: p>
11
111
122222
T p> blockQuote>Le code me semble aussi juste pour moi, peut-être que c'est un bug de compilateur?
voir ici P>
Le code a un comportement indéfini, de sorte que Bery fonctionnera probablement différemment (s'il fonctionne du tout) sur différentes plates-formes. Ce n'est pas un "bogue de compilateur" - avant de toujours utiliser ces mots, réfléchissez deux fois, puis réfléchissez à nouveau à nouveau à nouveau.
Merci :) Cela me semblait tellement étrange pour moi. Je n'ai pas vu l'Union. Je pensais que c'était une structure simple.
Normalement, lorsque vous attribuez une valeur arbitraire à un bool code> le compilateur le convertira pour vous:
bool z = (x != 0) ? true : false;
Oui, mais est-ce un bogue du compilateur, ou est-ce simplement indéfini dans les spécifications. Un compilateur peut toujours créer un ((((A! = 0) && (B! = 0)) || ((A == 0) && (B == 0))) au lieu de simplement vérifier les bits.
Il s'agit d'un comportement indéfini d'accéder à un membre d'une union autre que le dernier dans lequel une valeur a été stockée.
Si vous lisez un membre d'un syndicat qui est un membre différent que le dernier membre qui a été écrit, vous obtenez un comportement indéfini. Écrire un membre INT puis lire le membre Bool de l'Union pourrait entraîner quelque chose à tout point ultérieur du programme. P>
La seule exception est l'endroit où les syndicats sont une union des structures et toutes les structures contiennent une séquence initiale commune, auquel cas la séquence commune peut être lue. P>
Oui, mais si j'ai une structure avec un bool dedans, et je lis des données dans cette structure d'un fichier. De cette façon, je n'utilise pas les syndicats, mais obtenez toujours les "mauvaises" données dans la variable Bool.
Ensuite, c'est une autre question, ou éditez votre actuel et modifiez le code.
Encore une fois, comportement indéfini. Vous ne pouvez pas lire des modèles de bits arbitraires dans des variables C ++ et attendez-les à leur "travailler".
Afaict, la seule garantit que les états standard sont que toute valeur zéro arithmétique convertie en un bool code> avec être
false code> et tous les autres seront
true code>. De même, une valeur code> BOOL code> sera convertie en une valeur zéro dans tout type arithmétique pour
false code> et un pour
true code>. Au-delà de cela,
fwrite ((vide *) & b, taille de (B), 1, fp) code> écrira le nombre d'octets associés à
B code> de telle manière que
Fread ((vide *) & B, taille de (B), 1, FP) code> entraînera la même valeur. Rien n'est dit sur le nombre d'octets écrits ou sa valeur binaire. En outre, considérons que
tailleof (bool) code> et
tailleof (int) code> peut différer ...
Je crois ce que tu fais est appelé type punning: http://fr.wikipedia.org/wiki/type_punning P>
Le booléen est un octeen et l'entier est quatre octets. Lorsque vous attribuez 2 à l'entier, le quatrième octet a une valeur de 2, mais le premier octet a une valeur de 0. Si vous lisez le booléen à l'extérieur de l'Union, cela va prendre le premier octet. P>
EDIT: D'Oh. Comme l'indique Oleg Zhylin, cela ne s'applique qu'à un processeur Big-Endian. Merci pour la correction. P>
Je suppose que la plupart des gens sont sur des machines de petite endansion. Mais +1 pour le pointant de cela.
juste pour écrire mes points de vue: P>
est-ce que ça va? p>
Je ne sais pas si les spécifications spécifient quoi que ce soit à ce sujet. Un compilateur peut toujours créer un code comme celui-ci: ((A! = 0) && (B! = 0)) || ((A == 0) && (B == 0)) Lorsque cela comparait deux booléens, bien que cela puisse diminuer les performances. P>
À mon avis, ce n'est pas un bogue, mais un comportement non défini. Bien que je pense que chaque implémentatif devrait indiquer aux utilisateurs comment les comparaisons booléennes sont effectuées dans leur mise en œuvre. P> LI>
n'importe quel cas réel p>
La seule chose qui apparaît dans mon esprit, si quelqu'un lit des données binaires d'un fichier dans une structure, qui ont des membres BOOL. Le problème pourrait augmenter si le dossier a été effectué avec un autre programme qui a écrit 2 au lieu de 1 à la place du Bool (peut-être parce qu'il a été écrit dans un autre langage de programmation). P>
Mais cela pourrait signifier une mauvaise pratique de programmation. P> li> ol>
Un de plus: Dans les systèmes embarqués Ce bug pourrait être un problème plus important que sur un système "normal", car les programmeurs font généralement plus de "magique bit" pour faire le travail. p>
"Avis" ne vient pas dedans. C'est un bug ou un comportement non défini (ou quelque chose d'autre). Et le point entier du comportement non défini est que les responsables de mise en œuvre ne sont pas tenus de documenter quoi que ce soit, ni un comportement unique cohérent requis. Nécessitant ces choses l'auraient transformé en comportement défini par la mise en œuvre. Un comportement indéfini signifie que vous ne pouvez pas compter sur le comportement, même quand il semble fonctionner comme vous vous attendez.
Il n'est jamais prudent de supposer que ce que vous lisez à partir d'un fichier est correct, surtout si vous faites le tour du système de type en définissant des bits directement.
En ce qui concerne les systèmes intégrés, je suggérerais d'utiliser des types de données de taille fixe Toujours B> et d'être très explicite sur l'ordre d'octets. Si votre compilateur / mise en œuvre ne vous fournit pas vous, lancez votre propre en-tête et un tas de trucs de préprocesseur. Jetez un coup d'œil à Prefef.sourceforge.net pour une bonne collection de macros de préprocesseur définies par divers compilateurs.
Répondre aux questions posées, je pense que le comportement va bien et ne devrait pas être un problème dans le monde réel. Comme nous n'avons pas ^^ en C ++, je suggérerais! BOOL ==! Bool comme une technique de comparaison de bool sécuritaire. P>
De cette façon, chaque valeur non nulle dans la variable Bool sera convertie en zéro et chaque zéro est converti en une valeur non nulle, mais la plupart probablement l'une et la même chose pour toute opération de négation. p>
Comment cela s'est-il levé? Et comment! Bool ==! Bool résolvait le problème ici, c'est-à-dire qu'il demande au compilateur de comparer un octet zéro converti en Bool, avec la valeur BOOL vrai code> et les attentes à être égales.
- Est-ce que ça va? (Ceci a été testé avec g ++ 4.3.3) Je veux dire, si le compilateur doit être conscient que pendant la comparaison booléenne, toute valeur non nulle pourrait signifier VRAI? LI> ol>
Toute valeur entières non nulle (ou pointeur non null) représente vrai. Mais lors de la comparaison d'entiers et de bool, le bool est converti en Int avant la comparaison. P>
- Connaissez-vous des cas où cette affaire de coin pourrait devenir un véritable problème? (Par exemple, tandis que le chargement binaire des données d'un courant) li> ol> blockQuote>
C'est toujours un vrai problème. P>
est-ce que ça va? p>
Je ne sais pas si les spécifications spécifient quoi que ce soit à ce sujet. Un compilateur peut toujours créer un code comme celui-ci: ((A! = 0) && (B! = 0)) || ((A == 0) && (B == 0)) Lorsque cela comparait deux booléens, bien que cela puisse diminuer les performances. P>
À mon avis, ce n'est pas un bogue, mais un comportement non défini. Bien que je pense que chaque implémentatif devrait indiquer aux utilisateurs comment les comparaisons booléennes sont effectuées dans leur mise en œuvre. P> LI> ol> blockQuote>
Si nous passons par votre dernier code d'échantillon A et B sont BOOL et défini sur true en attribuant 1 et 2 respectivement (NOE les 1 et 2 disparaissent, ils sont maintenant vrais). P> Donc, rompre votre expression: p>
xxx pré> donc je m'attendrais toujours à ce que l'expression ci-dessus soit bien définie et toujours vraie. P>
Mais je ne sais pas comment cela s'applique à votre question initiale. Lors de l'attribution d'un entier à un BOOL, l'entier est converti en BOOL (comme décrit plusieurs fois). La représentation réelle de VRAI n'est pas définie par la norme et pourrait être un modèle de bit qui s'inscrit dans un bool (vous ne pouvez pas assumer un motif de bits en particulier). P>
Lorsque vous comparez le bool à int. dans un int d'abord puis comparé. p>
n'importe quel cas réel p>
La seule chose qui apparaît dans mon esprit, si quelqu'un lit des données binaires d'un fichier dans une structure, qui ont des membres BOOL. Le problème pourrait augmenter si le dossier a été effectué avec un autre programme qui a écrit 2 au lieu de 1 à la place du Bool (peut-être parce qu'il a été écrit dans un autre langage de programmation). P>
Mais cela pourrait signifier une mauvaise pratique de programmation. P> li> ol> blockQuote>
écrire des données dans un format binaire n'est pas portable sans connaissance.
Il y a des problèmes de taille de chaque objet.
Il y a des problèmes de représentation: p>
- Les entiers (ont une endience) li>
- float (représentation non définie (((généralement dépend du matériel sous-jacent)) li>
- bool (la représentation binaire est indéfinie par la norme) li>
- struct (le rembourrage entre les membres peut différer) li> ul>
Avec tous ceux-ci, vous devez connaître le matériel sous-jacent et le compilateur. Différents compilateurs ou différentes versions du compilateur ou même un compilateur avec différents drapeaux d'optimisation peuvent avoir des comportements différents pour tout ce qui précède. P>
Le problème avec Union P>
struct X { int a; bool b; };
GCC sonne juste le bit le moins significatif lors du fait de
! B code> et
B code> est de type
bool code>. Donc, un
1 code> devient
0 code> et inversement, sans ramification. En outre, lors du fait de
int A = B; code> rien n'est nécessaire pour être comparé (alors seul un geste est nécessaire). Il est donc logique de stocker un
bool code> en tant que numéro
0 code> et
1 code> (mais cela n'est pas spécifié par la norme). Dans votre code,
wb code> est pas i>
true code> (car GCC utilise
1 code> pour représenter true, pas
2 code>).
w.b code> a non i> valeur. Il a une représentation piège. Lire c'est comportement indéfini i>.