私のああ - これは全く保存されていません...
は、あなたがSUM_VARS(12, ...)
でこれを呼び出す想像 - 12一定で、メモリアドレスを持っているので、あなたのマクロが&12
で失敗しません。
SUM_VARS(n + 7, ...)
と呼んでください。あなたは–キャストを省略すると、– unsigned int* inta = &n + 7;
をキャストします。 nは配列ではないので、未定義の動作です!それがなかった場合でも、cはタイプchar
またはshort
でありながら、あなたは、nと完全に無関係な値へのポインタ... SUM_VARS(c, ...)
と
コールそれを取得している - あなたがして、変数c過去の記憶を読んでいる(未定義動作)。 OK、リトルエンディアンマシンでは、ビッグエンディアンマシンで、不要な部分をマスクすることになります。
これらのポインタはまったくなぜですか?
なぜ単に
#define SUM_VARS(a, b, c, d) \
((a) << 24 & 0xff000000) \
| \
((b) << 16 & 0x00ff0000) \
| \
((c) << 16 & 0x0000ff00) \
| \
((d) << 16 & 0x000000ff)
注意、B、C、Dの周りに括弧。ビットシフトが適用される前に、より低い優先順位の演算子を含む式が完全に評価されることを保証するためには、重要なことは非常にです。
あなたはこれに対して関数を使用すると、はるかに安全になります(Olafはこれを既に推奨しています)。
inline unsigned int sumVars(unsigned int a, unsigned int b, unsigned int c, unsigned int d)
{
return
(a << 24 & 0xff000000)
|
(b << 16 & 0x00ff0000)
|
(c << 16 & 0x0000ff00)
|
(d << 16 & 0x000000ff);
}
お知らせあなたは必要ありません:あなたは、関数呼び出しのオーバーヘッド(コンパイラは、この勧告に従うことを強制ではありませんが、このような単純な機能を備えた、最も可能性の高い意志を)保存したい場合は、インラインそれを作りますこれ以上内側の括弧は関数呼び出しの前に評価されます。
あなたは、さらに上に行きたい場合は、テンプレート関数にこれを拡張することができます:
template < typename T >
T sumAll(T t)
{
return t;
}
template < typename T, typename ... Values >
T sumAll(T t, Values ... values)
{
return t + sumAll(values...);
}
手立てのCません! – Olaf
マクロを手で解決すると、表示されます。とにかく関数を使わないのはなぜですか? – Olaf
C++タグが追加されました。プリプロセッサマクロ、テンプレート(特にreinterpret_cast)はあなたの感覚にあるはずです... – Aconcagua