3

私が64ビットに移植しようとしているCソースコードは、32ビット環境では警告なしに実行されます。コンパイルgcc(Ubuntu 4.4.1-4ubuntu9)4.4.1を使用して64ビットLinux環境でコンパイルすると、主に次の警告が表示されます。

warning: cast to pointer from integer of different size

上記の警告が最も多かった。uintptr_tタイプを使用しましたが、これらの警告のほとんどが削除されました。uintptr_tを使用して、型int /unsignedint を64ビットに変更できます。しかし、64ビットと互換性を持たせるために次のタイプを変更するにはどうすればよいですか?

typedef void*  POINTER;

次のコードを変更しました。

typedef unsigned int    ABC; 

の中へ

typedef uintptr_t ABC

次の警告が表示されました。

warning: passing argument 2 of ‘function’ from   incompatible pointer type
note: expected ‘ABC *’ but argument is of type ‘unsigned int *’

さらに、タイプdefを以前はintまたはunsigned intであったuintptr_tに変更した後、次のようなほとんどの警告が発生します。

warning: inlining failed in call to ‘abc_StringCopy’: call is unlikely and code size would grow

関数tptp_StringCopyは次のとおりです。

static __inline__ char* abc_StringCopy(void)
{
  char *copy;
  copy = (char*)Malloc(yyleng+1);
  strcpy(copy, yytext);
  return copy;

これらの警告を取り除くにはどうすればよいですか?

4

4 に答える 4

2

unsigned intuintptr_t64 ビット システムでは と互換性がありません。int64 ビット マシンでunsigned intは 32 ビット値のままですuintptr_tが、64 ビット型になります。型が呼び出される理由はuintptr_t、型がポインターと同じ幅の符号なし整数値であるためです。つまりuintptr_t、32 ビット マシンでは 32 ビット幅ですが、64 ビット マシンでは 64 ビット幅になります。

コードでは、これは、typedef変更により、64 ビット マシンNAT*では 64 ビット変数への 64unsigned int*ビット ポインターであるが、32 ビット変数への 64 ビット ポインターであることを意味します。

clause_ComputeSplitFieldAddressはまだパラメータを期待していunsigned int*ます。

于 2010-03-06T21:41:34.870 に答える
1

ここでの根本的な問題は、ポインターが 32 ビット整数型との間で損失なくキャストできると想定していることだと思います。これは 32 ビット コードでは当てはまりますが、64 ビット コードでは当てはまりません。ポインタは 64 ビット型です。これは、おそらく最も一般的な 32 ビットから 64 ビットへの移植の問題です。

NAT は実際には何を意図しているのでしょうか。構造体への不透明なポインター (32 ビット コードで 32 ビット整数としてドレスアップ) である場合は、uintptr_t ではなく void* として宣言するのが最適な場合があります。

于 2010-03-06T22:54:16.253 に答える
1

POINTER typedef を変更する明確な理由はありません。void ポインターは、32 ビットと 64 ビットの両方で引き続き void ポインターです (ただし、32 ビット バージョンは 64 ビット バージョンの半分のスペースを占有します)。問題が発生するのは、POINTER を乱用して何らかの整数として扱おうとした場合のみです。

clause_ComputeSplitFieldAddress のコードは示していませんが、関数が「NAT *」を受け取る場合、「unsigned int」のアドレスを渡すことができないことは明らかです。呼び出された場所を調べて、呼び出し元のコードを修正するための適切なアクションを決定する必要があります。基本的に、関連する unsigned int 変数を NAT 変数に変更します。

tptp_StringCopy 関数については、おそらく使用する必要がstrdup()あります。これにより、メモリ割り当てが失敗した場合に、すぐにクラッシュすることはおそらくないでしょう。

List_Cons() に関連する警告が表示されないため、すぐには対応できません。

一般に、32 ビットから 64 ビットへの問題の多くは、整数とポインターの間で型のパニングを行わないようにすることで対処できます。必要な場合は、 uintptr_t (したがって<inttypes.h>) を使用します。<inttypes.h>また、特定の typedef 名の変数型定義がある場合は、厳密に定義されている印刷およびスキャン形式を使用してください。たとえば、

PRIXPTR

uintptr_t 値をフォーマットするには:

printf("0x%08" PRIXPTR "\n", ptr_as_int);

これですべての問題が解決されるわけではありません。それはそれらの多くを扱います。

コンパイラーは、インライン化されていないコードについて必要に応じて警告する権利があります。インライン化できない関数のインライン化を要求しないことを除いて、それについてできることはあまりありません。

于 2010-03-07T02:36:12.720 に答える
-1

詳しい状況はわかりませんが、あなたが に変わっunsigned intたようuintptr_tです。前者は unsigned int で、後者は unsigned int pointerです。

一般に、これは有効な置換ではありません。

また、コードは「32ビットで警告なしで実行される」と述べましたが、64ビットのコンパイルでは警告が表示されます。しかし、警告なしに実行されるかどうかは問題ではありません。たぶん、警告なしでコンパイルされるということです。本当?変更したコードは、警告なしで 32 ビット用にコンパイルされますか? それは驚きです。

于 2010-03-06T20:58:44.430 に答える