Question

Je convertir un code compatible 32 bits en 64 bits - et je l'ai frappé un accroc. Je compile un projet x64 VS2008, et je reçois cet avertissement:

warning C4334: '<<' : result of 32-bit shift implicitly converted to 64 bits
(was 64-bit shift intended?)

Voici la ligne originale du code:

if ((j & (1 << k)) != 0) {

Et voici à quoi il ressemble si je suis conseils de Microsoft :

if ((j & (1i64 << k)) != 0) {

Est-ce sans danger, lorsque le code sera compilé sur 32 bits et 64 bits? Si oui, s'il vous plaît expliquer pourquoi je dois ajouter « I64 » à la fin, et pourquoi cela n'affectera pas une compilation 32 bits. Dans le cas contraire, un travail autour serait très apprécié.

Au-delà de cela, j'ai ce qui ressemble à un peu plus délicat encore de code.

if (id[j] != id[j ^ (1u << k)]) {

Je comprends que le « u » signifie que le chiffre est non signé, mais quel est le point précisant que sur une valeur qui ne dépasse pas la valeur maximale signée ... Je suppose que cela a quelque chose à voir avec le décalage binaire?

Était-ce utile?

La solution

1 est de type int selon la norme C de. 64 bits int Microsoft compilateur a sizeof = 4 octets, cela signifie que int est variable de 32 bits. 1i64 est de type __int64.

Lorsque vous utilisez l'opérateur de décalage du type du résultat est le même que le type de l'opérande gauche. Cela signifie que le passage 1 vous obtiendrez résultat 32 bits. compilateur Microsoft suppose qu'il pourrait être pas ce que vous attendez (sur la plate-forme 64 bits) et vous donne un message d'avertissement.

Lorsque vous utilisez résultat 1i64 sera 64 bits sur les deux plates-formes. j et 0 seront implicitement casted 64 bits. Ainsi, toute l'expression sera calculée dans les variables 64 bits et le résultat sera bool.

Donc, en utilisant 1i64 est en sécurité sur les deux (32/64) des plates-formes.

Autres conseils

Le suffixe i64 est Microsoft spécifique. Pour être plus portable (si vous êtes inquiet à ce sujet), vous pouvez utiliser la macro INT64_C() de stdint.h:

#include <stdint.h>

// ...

if ((j & (INT64_C( 1) << k)) != 0) { ... }

Malheureusement, MS n'a pas stdint.h dans le cadre de leur bibliothèque C (la plupart des autres compilateurs semblent avoir), mais heureusement, vous pouvez obtenir un à partir de plusieurs sources:

Maintenant, vous aurez un travail constant qui va 64 bits avec une grande variété de compilateurs.

En ce qui pourquoi vous voudrez peut-être besoin ou la valeur 64 bits, cela dépend des types des différentes parties de l'expression. Il serait utile de connaître les types de id, j et k pour être en mesure de répondre si vous avez besoin du suffixe « u » sur la constante ou non, et quel effet cela pourrait avoir.

Je crois 1i64 devrait être signé, entier de 64 bits. Je ne peux pas proclamer une expertise dans la mise en œuvre de Microsoft, mais dans GCC, la solution pour supporter les entiers 64 bits sur les processeurs 32 bits a été de faire de longs désire ardemment double-mots en utilisant struct et diverses macros magie noire. Par conséquent, i64 devrait être compatibles.

En ce qui concerne le dernier bit de voodoo - le seul point en spécifiant 1u il est parce qu'il est possible que si k est assez grand, le résultat du changement rencontrerait / dépasser 32 bits de stockage, auquel cas le résultat sera différente si l'opérande de LH est traitée comme une signature ou un nombre entier non signé.

Etant donné que le code est « and'ing la j variable de 64 bits avec le résultat d'un bit de décalage (32 bits), le résultat sera « étendu » à 64 bits par le compilateur.

Vous voulez sans doute d'être en contrôle de la façon dont le second opérande au « et » est calculé, de sorte que le compilateur vous suggère d'utiliser les 64 bits en plein faisant le premier opérande un __int64. Ceci est sûr en 32 bits, mais vous devriez vraiment regarder le type de j de décider de l'opérateur étant 32 ou 64 bits.

Cela est particulièrement important dans le second bit, où le résultat est utilisé comme un indice.

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