[解決済み】「ポインタから異なるサイズの整数へのキャスト」エラーが発生するのはなぜですか?
質問内容
次の行(pure c)は、次のようにきれいにコンパイルされます。 ウィンドウ (win7 64 bits + codeblocks 13 + mingw32) と デビアン (wheezy 32 bits + codeblocks 10 + gcc) で警告が表示されます。 カーリー (64 bits + codeblocks + gcc)です。何かコメントはありますか?つまり、同じ行がWindows & debianで何の警告もなくコンパイルされるのに、なぜこの警告が出るのでしょうか?
void* foo(void *dst, ...) {
// some code
unsigned int blkLen = sizeof(int); // this line ok.
unsigned int offset = (unsigned int) dst % blkLen; // warning here!
// some code cont...
}
codeblocksのメッセージは、「"」です。 のエラーが発生しました。 ポインタから異なるサイズの整数へのキャスト [-Werror=pointer-to-int-cast]"
注:私のコンパイラのオプションは
-std=c99 -Werror -save-temps
(3つのシステムで同じ)。
2を編集します。
以下のプリプロセッサの行を使って、なんとか警告を出さずにコンパイルできるようになりましたが。
Keith Thompson (下記参照) は、この問題に関して重要な指摘をしています。そこで、私の最後の決断は
uintptr_t
がベターな選択でしょう。
1を編集します。 皆さん返信ありがとうございました。すべての返信にあるように、この問題は32ビットと64ビットの問題です。私は以下のプリプロセッサの行を挿入しました。
#if __linux__ // or #if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#else
#if _WIN32
#define ENVIRONMENT32
#else
#define ENVIRONMENT64
#endif
#endif // __linux__
#ifdef ENVIRONMENT64
#define MAX_BLOCK_SIZE unsigned long long int
#else
#define MAX_BLOCK_SIZE unsigned long int
#endif // ENVIRONMENT64
というように、問題の行を置き換えた。
unsigned int offset = (MAX_BLOCK_SIZE) dst % blkLen;
これで、すべてOKのようです。
どのように解決するのですか?
警告の理由は、コンパイラが、あなたが
int
を往復しています。これは64ビットマシンが登場する以前にはよく行われていたことで、安全でも合理的でもありません。もちろんここでは、コンパイラはあなたがこのようなことをしていないことを明確に知ることができますし、このような場合に警告が出ないようにするほど賢ければいいのですが、そうではありません。
警告や、変換後の値が負である場合の間違った結果という、より厄介な問題を回避する、クリーンな代替案は以下の通りです。
unsigned int offset = (uintptr_t) dst % blkLen;
をインクルードする必要があります。
stdint.h
または
inttypes.h
を持つようにします。
uintptr_t
を利用することができます。
関連
-
[解決済み】stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み】ヒープ割り当てで初期化されていない値が作成された
-
[解決済み】エラー。非スカラー型への変換を要求された
-
[解決済み】C言語でint64_t型を表示する方法
-
[解決済み】コンパイラの警告 - 真理値として使用される代入の周囲に括弧を付けることを推奨する
-
[解決済み】malloc():メモリ破壊
-
[解決済み】エラー:不明な型名'bool'
-
[解決済み] エラー: `itoa` はこのスコープで宣言されていません。
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] C言語では、なぜポインタを解放する前にキャストする人がいるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Valgrind が "Invalid write of size 8" で文句を言う。
-
[解決済み] Connect: ソケット以外でのソケット操作
-
[解決済み] clang: error: linker command failed with exit code 1が表示されるのはなぜですか?
-
[解決済み】cudamalloc()の使用。) なぜダブルポインタなのか?
-
[解決済み】ヒープ割り当てで初期化されていない値が作成された
-
[解決済み】警告:組み込み関数'printf'の非互換な暗黙の宣言(デフォルトで有効]
-
[解決済み] char pointers: 'char*' から 'char' への無効な変換?
-
[解決済み】execvp: バッドアドレスエラー
-
[解決済み】シンプルなC言語のscanfが機能しない?重複
-
[解決済み] 警告: 異なるサイズの整数への/からのポインタへのキャスト