33 votes

Est-il prudent de memset bool to 0?

Supposons que j'ai un certain héritage de code qui ne peut pas être modifié, sauf si un bug est découvert, et il contient ce code:

bool data[32];
memset(data, 0, sizeof(data));

Est-ce un moyen sûr de régler tous bool dans le tableau à une false de la valeur?

Plus généralement, est-il sûr d' memset un bool de 0 afin de rendre sa valeur en false?

Est-il garanti pour fonctionner sur tous les compilateurs? Ou dois-je demander un correctif?

25voto

Est-il garanti par la loi? Pas de.

C++ ne dit rien au sujet de la représentation de l' bool valeurs.

Est-il garanti par la réalité pratique? Oui.

Je veux dire, si vous voulez trouver une implémentation C++ qui ne représente pas boolean false comme une séquence de zéros, je vous souhaite bonne chance. Étant donné qu' false doit convertir implicitement à l' 0, et true doit convertir implicitement à l' 1, et 0 doit convertir implicitement à l' false, et les non-0 doit convertir implicitement à l' true ... eh bien, vous seriez stupide de mettre en œuvre toute autre manière.

Si cela signifie qu'il est "sûr" c'est à vous de décider.

Je n'ai pas l'habitude de dire cela, mais si j'étais dans votre situation, je serais heureux de laisser cette diapositive. Si vous êtes vraiment intéressé, vous pouvez ajouter un test exécutable sur votre distribuable pour valider la condition sur chaque plate-forme cible avant d'installer le projet réel.

9voto

Olipro Points 953

Pas de. Il n'est pas sûr (ou, plus précisément, portable). Cependant, il est probable que des œuvres en vertu du fait que votre typique de mise en œuvre seront:

  1. utilisez 0 pour représenter une valeur de type boolean (en fait, le C++ spécification exige)
  2. générer un tableau d'éléments qui memset() peut traiter.

Cependant, la meilleure pratique dicter à l'aide bool data[32] = {false} - de plus, ce sera probablement libérer le compilateur jusqu'à l'interne de représenter la structure différemment, car l'utilisation d' memset() pourrait entraîner la génération d'un 32 tableau d'octets de valeurs plutôt que, disons, un seul de 4 octets qui s'intégrera parfaitement au sein de votre CPU moyenne registre.

8voto

Shafik Yaghmour Points 42198

Je crois que c'quelconque, bien qu'il semble probable que la représentation sous-jacente de l' false serait tous les zéros. Coup de pouce.Conteneur dépend de ce que bien (c'est moi qui souligne):

Coup de pouce.Conteneur utilise std::memset avec une valeur de zéro pour initialiser certaines les types comme dans la plupart des plates-formes de cette initialisation des rendements souhaités la valeur d'initialisation avec l'amélioration des performances.

À la suite de la norme C11, coup de pouce.Conteneur suppose que pour tout de type entier, l'objet de la représentation, où tous les bits sont à zéro doit être une représentation de la valeur zéro dans ce type. Depuis _Bool/wchar_t/char16_t/char32_t sont également les types d'entiers en C, il considère toutes les C++ intégrale types de initializable par std::memset.

Cette C11 citer qu'elles-ils point une justification provient en fait d'un C99 défaut: défaut 263: de zéro pour tous les bits de représentations qui a ajouté ce qui suit:

Pour tout type entier, l'objet de la représentation, où tous les bits sont zéro doit être une représentation de la valeur zéro dans ce type.

Alors la question qui se pose ici l'hypothèse est correcte, sont l'objet sous-jacent de la représentation pour entier compatible entre le C et le C++? La proposition de Résolution de la différence entre le C et le C++ en ce qui concerne l'objet de la représentation des entiers a tenté de répondre dans une certaine mesure qui, autant que je sache, n'a pas été résolu. Je ne trouve pas de preuve concluante de cette dans le projet de norme. Nous avons un couple de cas où des liens vers le C standard explicitement à l'égard de types. Section 3.9.1 [de base.fondamentaux] dit:

[...] Les entiers signés et non signés les types integer, doit satisfaire à la contraintes indiquées dans la norme C, section 5.2.4.2.1.

et 3.9 [de base.types] qui dit:

L'objet de la représentation d'un objet de type T est la séquence de N unsigned char objets pris par l'objet de type T, où N est égal à sizeof(T). La valeur de la représentation d'un objet est l'ensemble de bits que la valeur de type T. Pour trivialement copiable types, la valeur la représentation est un ensemble de bits dans la représentation des objets qui détermine une valeur, qui est un élément discret d'un mise en œuvre-ensemble défini de valeurs.44

où la note de bas de page 44(ce qui n'est pas normatif) dit:

L'intention est que le modèle de mémoire de C++ est compatible avec celle de ISO/IEC 9899 Langage de Programmation C.

Le plus éloigné, le projet de norme devient la spécification de la représentation sous-jacente de bool est dans la section 3.9.1:

Types bool, char, char16_t, char32_t, wchar_t, et la signature et entier non signé types sont appelés collectivement les types intégraux.50 synonyme de type intégral est de type entier. Les représentations de l' partie intégrante types de définir des valeurs par l'utilisation d'un pur numération binaire système.51 [ Exemple: la présente Norme Internationale permet de 2 en complément, 1er complément et signé ampleur des représentations les types intégraux. fin de l'exemple ]

l'article dit aussi:

Les valeurs de type bool sont vraies ou fausses.

mais tout ce que nous savons de l' true et false est:

Les littéraux Booléens sont les mots clés de faux et de vrai. Ces littéraux sont prvalues et avoir le type bool.

et nous savons qu'ils sont convertibles 0 un 1:

Un prvalue de type booléen peut être converti en prvalue de type int, avec faux en devenant zéro et devenir un vrai.

mais cela nous amène pas plus près de la représentation sous-jacente.

Aussi loin que je peux dire, le seul endroit où les références classiques du sous-jacent valeur de bit, en plus de rembourrage bits a été supprimé par rapport de défaut 1796: Est tous les bits à zéro pour les caractères null une véritable exigence? :

Il n'est pas clair qu'un programme portable peut examiner les bits de la représentation; au lieu de cela, il semble se limiter à examiner les bits du nombre correspondant à la valeur de la représentation (3.9.1 [de base.fondamentaux] l'alinéa 1). Il peut être plus approprié d'exiger que le caractère null de la valeur de comparer égal à 0 ou '\0' au lieu de spécifier le motif de bits de la représentation.

Il y a plus de rapports de défaut que de traiter les lacunes dans la norme par rapport à ce qui est un peu et de la différence entre la valeur et l'objet de la représentation.

Pratiquement, je m'attends à ce que cela fonctionne, je ne voudrais pas le considérer en sécurité puisque nous ne pouvons ongles cela dans le standard. Avez-vous besoin de la changer, pas clair, vous avez clairement un non-trivial compromis impliqués. Donc, en supposant que cela fonctionne maintenant, la question est de savoir si nous considérons qu'il est susceptible de rompre avec les futures versions de différents compilateurs, qui est inconnu.

8voto

Mark B Points 60200

À partir de 3.9.1 / 7:

Les types bool, char, char16_t, char32_t, wchar_t, ainsi que les types entiers signés et non signés sont collectivement appelés types intégraux. Un synonyme de type intégral est un type entier. Les représentations des types intégraux doivent définir les valeurs à l'aide d'un système de numération binaire pur.

Compte tenu de cela, je ne vois aucune implémentation possible de bool qui ne représenterait pas faux comme étant un bit 0.

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