2012-08-03 53 views
10

レガシーコードからgcc警告を削除しています。解決方法:Cコードで「異なるサイズの整数からポインタへキャスト」警告?

は型キャストを通じて、「異なるサイズの整数からポインタにキャスト」警告を抑止することが可能です:

example: 

some_struct *ptr = func() // func() returns an integer. 

を誰かが、このようなgccの警告を解決する方法を私を導いてくださいことはできますか?

+7

なぜstructポインタに整数を配置したいのですか? – Jay

+0

それは可能ですが、それが正しい方法で行くケースはまれです。 –

+0

"出力"差異の過負荷ですか?(入力パラメータではありません) –

答えて

19

まず、funcを修正して(そのソースを変更することが許可されている)、修正してください。ポインターで計算を行うことができれば、ポインターとリターンポインターでそれらを実行します。場合によっては、アドレスを整数として扱う有効な理由があります(たとえば、特殊コードの配置問題を扱うなど)。その場合はにuintptr_tタイプ(stdint.hで定義)を使用するように変更してください。必要に応じてポインタを整数として扱うように設計されています。 (何らかの理由で符号付き算術が優れている場合はintptr_tもありますが、一般的には符号なしuintptr_tが面倒ではありません。)好ましくは、それを返すときfuncはポインタにuintptr_tを変換する必要があり、そうfuncの戻り型は何か、おそらくsome_struct又はvoidへのポインタ()であろう。

funcを修正できない場合は、キャストを使用して、実行中の変換を実行することをコンパイラに指示できます。しかし、この特定のエラーメッセージは、単にポインタを整数に変換されていないことを通知されますが、他のサイズ(例えば、8バイト)のポインタにワンサイズ(例えば、4バイト)の整数に変換されます。このコードは、もともとfuncによって返された整数型がポインタ型と同じサイズを持っていたシステムのために書かれたそうですが、あなたは今、ポインタ型は、その整数のサイズよりも大きいか、小さいシステムでコンパイルされています。

この場合、funcによって実行された計算が新しいアーキテクチャで機能することを確認する必要があります。 32ビットの値しか返さない場合は、常に正しい値を保持しますか?つまり、上位32ビットが欠けても何も失われません。 funcが計算するアドレスは、それが使用する整数型の最大値を超えることはありませんか? funcが符号付き整数型を使用している場合は、符号ビットも考慮してください。

funcによって返される値が正しいことを確認した場合は、some_struct *ptr = (some_struct *) (intptr_t) func();などの明示的なキャストを使用できます。

6

私のgccはあなたが引用した警告を表示しません。あなたのコードにキャストがないので、それはまた不思議です。

私は警告

assignment makes pointer from integer without a cast 

を取得するには、 "キャストなし" の部分に注意してください。あなたが合わないfuncの戻り値の型IFFあなたの警告(「異なるサイズの整数からポインタへのキャスト」)を取得します、そして、

some_struct *ptr = (void*)func(); 

:したがって、あなたは(動作を変更せずに)キャスティングすることによりサイレントgccを作ることができます住所用。これは、適切な整数型に、例えば、func()をさらに流し込むことによって沈黙させることができる。 intptr_t:あなたは本当にポインタに間違ったサイズの整数に変換したいという仮定の下で

some_struct *ptr = (void*)(intptr_t)func(); 

このすべて。おそらく、コードを修正する方が良い考えです。

3

二つの可能性がここにあります

  1. funcは、整数への実際のポインタをキャストしています。後にポインタとして使用されます。
  2. funcは、ポインタに格納されている整数を返しています。 ptrは後に整数にキャストされ、整数として使用されます。最初のケースで

intは、Windowsを含むことが最も64-bit memory modelsになり、データポインタ、(のサイズよりも小さい場合、funcからの戻り値は、情報を失い、そして潜在的にクラッシュしたり悪化しますおよびLinux)。その場合は、返品タイプfuncintptr_tに変更してください。 Using intptr_t instead of void*?およびWhy/when to use `intptr_t` for type-casting in C?を参照してください。

第2のケースでは問題は少なくなりますが、エンディアンの問題に対処するには、intptr_tsome_struct *ptr = (some_struct *)(intptr_t)func();以降、int value = (int)(intptr_t)ptr;にキャストする必要があります。この問題の説明については、GLib Type Conversion Macrosを参照してください。

関連する問題