gccとVSの両方で
int pos = -1 * sizeof(obj);
を交換してください。 VSの下でエラーが発生するのは、恐らく警告をエラーとして扱うオプション/WX
を有効にしたからです。簡単な解決策は、乗算の前にintにsizeof(obj)
をキャストすることです:
int pos = -1 * static_cast<int>(sizeof(obj));
長い説明:この式で
:
int pos = -1 * sizeof(obj);
-1
はタイプint
のものであり、sizeof(obj)
はですsize_t
と入力してください。私たちが知る限り、size_t
は符号なし整数 - 私はそれが4または8バイトの幅であると思う。コンパイラは、乗算を行う前に両方のオペランドを共通の型に変換しようとします。これらの変換は暗黙的です。
ここで適用される変換規則は、符号付き整数に符号なしが掛けられ、符号なしオペランドが符号付きオペランドと同じかそれ以上の場合、符号付きオペランドは符号なしに変換されます。
その場合sizeof(int)
は4バイトであり、sizeof(size_t)
は8つのバイトは、次に-1
最初0xffffffffffffffff
に等しいstatic_cast<size_t>(-1)
に変換されます。その後、乗算が行われ、その後、別の変換が適用されます。乗算の結果はintに変換されます。 sizeof(obj)
はコンパイル時に認識されているため、コンパイラは正確な値を知っています。sizeof(obj)
が1の場合、乗算の結果は0xffffffffffffffff
であり、大きすぎてint
変数に割り当てられませんので、コンパイラは暗黙の変換について警告します。最後のフェーズの
打ち鳴らすの知らせる乗算の結果はintに変換され、(x64のコンパイル、はsizeof(size_tの)== 8):
main.cpp:15:17: warning: implicit conversion from 'unsigned long' to 'int' changes value from 18446744073709551615 to -1 [-Wconstant-conversion]
int pos = -1 * sizeof(obj);
~~~ ~~~^~~~~~~~~~~~~
size_t
サイズに応じて
は、コンパイラは異なる、ここで警告を与えます
gccが似ていますが、あまり有益である(x64のコンパイル、はsizeof(size_tの)== 8)(18446744073709551615が0xffffffffffffffffです):
一方
main.cpp:16:29: warning: overflow in implicit constant conversion [-Woverflow]
int pos = -1 * sizeof(obj);
のVisual Studio 2015の-1 unsigned型へ(x86のビルドで、はsizeof(size_tの)== 4)の変換について警告:私はそれがこの変換static_cast<size_t>(-1)
について通知したと
warning C4308: negative integral constant converted to unsigned type
。
と定数値の切り捨てについてのx64で(のsizeof(size_tの)== 8)(GCCと打ち鳴らす示す同上警告)
warning C4309: 'initializing': truncation of constant value
が、何らかの理由でC4308も、示さなくなりましたtho -1はまだ符号なし積分に変換されています。
Marcin、ありがとうございました。今はプログラムが実行されていますが、プログラムの異常終了は起こっています。知識を共有してくれてありがとう。 – ishtiaq