Lancer un personnage dans un court métrage non signé: que se passe-t-il dans les coulisses?

StackOverflow https://stackoverflow.com/questions/402616

  •  03-07-2019
  •  | 
  •  

Question

Étant donné ce champ:

char lookup_ext[8192] = {0}; // Gets filled later

Et cette déclaration:

unsigned short *slt = (unsigned short*) lookup_ext;

Que se passe-t-il dans les coulisses?

lookup_ext [1669] renvoie 67 = 0100 0011 (C), lookup_ext [1670] renvoie 78 = 0100 1110 (N) et lookup_ext [1671] renvoie 68 = 0100 0100 (D); pourtant slt [1670] renvoie 18273 = 0100 0111 0110 0001.

J'essaie de porter cela en C #, donc en plus d'un moyen facile de s'en sortir, je me demande aussi ce qui se passe vraiment ici. Cela fait longtemps que j'utilise C ++ régulièrement.

Merci!

Était-ce utile?

La solution

La déclaration que vous affichez ne transforme pas un caractère en un court-circuit non signé, elle envoie un pointeur sur un caractère en un pointeur en un court-circuit non signé. Cela signifie que les conversions arithmétiques habituelles des données pointées ne se produiront pas et que les données de caractère sous-jacentes seront simplement interprétées comme des courts-circuits non signés lorsqu’elles sont consultées via la slt variable.

Notez que sizeof(unsigned short) ne sera probablement pas le même, de sorte que slt[1670] ne correspondra pas nécessairement à lookup_ext[1670]. Il est plus probable - si, par exemple, lookup_ext[3340] soit égal à deux - de correspondre à lookup_ext[3341] et à <=>.

Savez-vous pourquoi le code original utilise cet aliasing? Si cela n'est pas nécessaire, il peut être intéressant d'essayer de nettoyer le code C ++ et de vérifier que le comportement n'a pas été modifié avant de le transférer.

Autres conseils

Si je comprends bien, la conversion de type convertira un tableau de caractères de taille 8192 en un tableau int court de taille égale à 4096, ce qui correspond à 4096.

Je ne comprends donc pas ce que vous comparez dans votre question. slt [1670] doit correspondre à lookup_ext [1670 * 2] et à lookup_ext [1670 * 2 + 1].

Eh bien, cette déclaration

char lookup_ext[8192] = {0}; // Gets filled later

Crée un tableau localement ou non localement, selon l’emplacement de la définition. En l'initialisant ainsi, avec un initialiseur agrégé, tous ses éléments seront initialisés à zéro (le premier explicitement, les autres implicitement). Par conséquent, je me demande pourquoi votre programme génère des valeurs non nulles. À moins que le remplissage ne se produise avant la lecture, cela a du sens.

unsigned short *slt = (unsigned short*) lookup_ext;

Cela interprétera les octets constituant le tableau comme des objets courts non signés lorsque vous lirez à partir de la cible de ce pointeur. Strictement parlant, le comportement ci-dessus est indéfini, car vous ne pouvez pas être sûr que le tableau est correctement aligné, et vous liriez à partir d'un pointeur qui ne pointe pas sur le type du type pointé d'origine (char non signé & Lt; - < !> gt; unsigned short). En C ++, le seul moyen portable de lire la valeur dans un autre pod (données anciennes). C’est toutes les structures et tous les types simples possibles en C (comme short), d’une manière générale, en utilisant des fonctions de bibliothèque telles que: memcpy ou memmove.

Donc, si vous lisez *slt ci-dessus, vous interpréterez les sizeof(*slt) premiers octets du tableau et tenterez de le lire comme un signe non signé (appelé type pun).

Quand vous faites & "unsigned short slt = (unsigned short )" lookup_ext; & ", le no. d'octets équivalents à la taille de (unsigned short) sont extraits de l'emplacement indiqué par lookup_ext et stockés à l'emplacement indiqué par slt. Puisque unsigned short serait de 2 octets, les deux premiers octets de lookup_ext seraient stockés à l'emplacement indiqué par slt.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top