7
votes

Problème avec l'opérateur dans le projet BITS DELPHI 64

Je porte un projet Delphi à 64 bits et j'ai un problème avec une ligne de code qui a le in code> opérateur.

Le compilateur augmente cette erreur p>

Types incompatibles E2010: «Integer» et 'intT64' P> blockQuote>

J'ai écrit cet exemple d'application pour reproduire le problème. p> xxx pré>

Ce code fonctionne bien en 32 bits, mais pourquoi ne compilait-t-il pas dans Delphi Xe2 64 bits? Comment je peux résoudre ce problème? P>

* update * strong> p>

Il semble que ma poste a provoqué beaucoup de confusion (désolé pour cela), juste pour expliquer Le code d'origine que le portage est plus complexe et je viens d'écrire ce code comme un exemple pour illustrer le problème. Le code d'origine utilise un opérateur utilisé pour vérifier si une valeur (mineure que 255) appartient à un groupe de valeurs (toutes mineures ou égales à 255), comme P>

i in [0,1,3,50,60,70,80,127,High(LArray)] 


4 commentaires

Vous pouvez envisager le cardinal plus rapide (I) <= cardinal (haut (L)) qui effectuera la comparaison avec un seul opcode et résoudre le problème de la coulée de type.


Vous devriez faire très attention à vous assurer que élevé (Larray) <= 255


@Arnaud ce qui vous fait penser que la performance est si importante? Pourquoi préféreriez-vous utiliser du CRYPTIQUE difficile à lire le code avec des erreurs de nuance cachées et de gamme? Cela n'a aucun sens pour moi. Ressemble à un cas classique d'optimisation prématurée.


@salvador Si vous allez utiliser des ensembles de cette façon, assurez-vous que votre code contient une affirmation que élevé (L)> = faible (octet) et élevé (L) <= haut (octet ) et tout ira bien.


3 Réponses :


8
votes

13 commentaires

Si vous utilisez haut, vous devez également utiliser bas. Le codage dur A 0 peut fonctionner, mais en utilisant des travaux toujours bas.


Selon les jeux Docs, il doit avoir un type de base, pas plus de 256 éléments. Alors peut-on [0..Integer (High (L))] peut-il fonctionner?


@DavidHeffernan [0..Integer (haut (L))] n'est pas égal à [0, entier (haut (L))]


@Krom, le test de fonction Inrange Si une valeur est comprise entre une valeur min et max, donc dans ce cas, n'est pas applicable car si i ineger (haut (L))] Ensuite, est équivalent à écraser si (i = 0) ou (i = entier (haut (l)))) puis


Ne testerait pas (i = 0) ou (i = élevé (L)) serait plus correct que dans l'opérateur dans ce cas?


@Rruz j'ai corrigé ma réponse. Je n'aime pas la fonte Bien que je soupçonne que vous l'avez écrit pour illustrer la question des types ordinaux et des ensembles plutôt que de recommander son utilisation en code réel. J'ai senti que c'était assez important pour orthographier dans une réponse. J'espère que tu n'es pas offensé!


@Krom, peut-être pour vérifier deux valeurs, mais pour plusieurs valeurs, l'opérateur est très utile, par exemple myvalue dans [1,3,4,6..20]


@Krom à mon avis dans est beaucoup plus lisible, mais la distribution est intenable.


@Rruz: J'avais des problèmes d'utilisation de ceux-ci à Delphi7. Est-il prudent de l'utiliser comme ça par ex. Xe2? Je veux dire i dans [-5, 45, $ FFFF, 4000000000] cas


@DavidHeffernan Pas de problème :), comme vous dites que je concentre ma réponse pour expliquer le problème et suggérer une solution rapide . Personnellement, je préfère utiliser l'opérateur in` que d'écrire un si sentene avec multiples ou


@RRUZ: PLZ Voir Réponse Sergs, est-ce toujours correct pour XE2 64bit?


@Rruz Voir ma dernière mise à jour. L'opérateur dans n'est tout simplement pas adapté à un but ici.


Ou peut-être plus rapide cardinal (i) <= cardinal (haut (L)) qui fera la comparaison avec un seul opcode et résoudre le problème.



5
votes

Qu'est-ce que Rruz dit est tout à fait correct.

Pour ajouter un peu plus d'explications, dans les indices de réseau dynamique 64 bits, peut être de 64 bits de large. Ceci est clairement nécessaire, par exemple, lorsque vous travaillez avec un grand bloc de mémoire TBYtes. Et donc la fonction élevé doit renvoyer une valeur d'un type suffisamment large pour contenir tous les indices possibles. Donc, haut lorsqu'il est appliqué à une matrice dynamique, renvoie une valeur de type int64 .

une fois que vous avez commencé à compiler 64 bits Code, le code L'opérateur n'est pas nonité au problème que vous essayez de résoudre. Bien que vous puissiez utiliser le casting que Rruz suggère, il peut être plus clair d'écrire le code comme celui-ci xxx

tandis que le dans opérateur fait assez lisible. Code, c'est mon avis qu'un casting à entier n'est pas acceptable ici. Cela permettra simplement de définir un piège pour que vous puissiez tomber lorsque vous avez d'abord un tableau avec plus de haut (entier) éléments. Lorsque cela se produit, le code avec la distribution cessera de fonctionner.

Mais en fait, les problèmes courent beaucoup plus profond que cela. La version dans du code échoue longtemps avant d'atteindre haut (entier) éléments. Il s'avère que votre code, tandis que cela compile, ne fonctionne pas vraiment. Par exemple, considérons ce programme: xxx

Vous pouvez vous attendre à ce que ce programme de sortie true mais il sortirait en fait false . Si au lieu de cela, vous deviez écrire xxx

puis les rapports du compilateur: xxx

Le problème fondamental ici est que les ensembles sont limités à 256 éléments afin que vous ayez une matrice de longueur supérieure à celle-là, votre code cesse de fonctionner.

Malheureusement, le soutien de Delphi pour les ensembles est tout simplement insuffisant et a besoin d'attention urgente.


Je me demande aussi si vous vouliez réellement écrire xxx

si oui, je vous recommanderais d'utiliser la fonction inrange de math . xxx

ou même meilleur xxx


2 commentaires

Très bon d'avoir ceci est enfin sorti. Vous méritez plus de upvotes pour une réponse vraiment correcte et approfondie)


+1 Bonne réponse David, j'ai mis à jour ma réponse aussi avec plus d'informations sur l'opérateur dans l'opérateur.



2
votes

Le problème le plus grave avec le code OP est que dans code> est limité à définir la taille code>, c'est-à-dire [0..255]. Essayez ceci dans n'importe quelle version 32 bits de Delphi pour éviter le problème 64 bits:

{$R+}
procedure TForm1.Button2Click(Sender: TObject);
var
  I: Integer;
  A: array of Integer;

begin
  SetLength(A, 1000);
  I:= 999;
  if I in [0, High(A)] then ShowMessage('OK!');  // Project .. raised exception
                          // class ERangeError with message 'Range check error'.
end;


2 commentaires

@LU RD - pas de fautes de frappe, longueur (l) <= 256 ==> élevé (L) <= 255 si vous le voulez le dire.


Désolé, mélangé haut et longueur.