C/GL:符号なしの整数の配列で-1をセンチネルとして使用する
-
28-10-2019 - |
質問
いくつかのGLコードで頂点インデックスの配列を渡しています...各要素はGlushortです
センチネルで終了して、配列自体に沿って毎回配列の長さを積極的に渡す必要がないようにしたいと思います。
#define SENTINEL ( (GLushort) -1 ) // edit thanks to answers below
:
GLushort verts = {0, 0, 2, 1, 0, 0, SENTINEL};
一部の要素には値0があるため、0を使用して終了できません
-1を使用できますか?
私が理解するために、これは最大の整数に包まれますGlushortは表現できます。
しかし、この動作はCで保証されていますか?
(このタイプのMAX_INT等価定数が見つかりません。そうしないと、それを使用しています)
解決
もしも GLushort
実際、署名されていないタイプです (GLushort)-1
の最大値です GLushort
. C標準はそれを保証します. 。したがって、安全に使用できます -1
.
たとえば、C89にはありませんでした SIZE_MAX
最大値のマクロ size_t
. 。ユーザーがASによって携帯的に定義することができます #define SIZE_MAX ((size_t)-1)
.
これがコードのセンチネル値として機能するかどうかは、 (GLushort)-1
コード内の有効な非センチネル値です。
他のヒント
GLushort
です UNSIGNED_SHORT
タイプ化されたタイプ unsigned short
, 、そしてそれ、それ、c 保証しません OpenGLは、2^16-1の範囲を持つ値として想定しています(仕様の第4.3章)。実質的にすべての主流のアーキテクチャでは、このやや危険な仮定も当てはまります(私はどこであっているのかわかりません unsigned short
異なるサイズがあります)。
そのため、あなた できる -1を使用しますが、たとえばキャストを忘れた場合、それは厄介です。 if()
声明、あなたはそうすることができます ラッキー そして、「比較は決して真実ではない」についてのコンパイラ警告を取得します。 不運 また、コンパイラは静かにブランチを最適化し、その後、一見完璧なコードが間違っている理由を検索するために何日も費やします。さらに悪いことに、それはすべてデバッグビルドで正常に機能し、リリースビルドの爆弾のみが正常に機能します。
したがって、使用します 0xffff
JV42がアドバイスしているように、はるかに好ましいので、この落とし穴を完全に回避します。
私はグローバルな価値の定数を作成します:
const GLushort GLushort_SENTINEL = (GLushort)(-1);
署名された整数が2の補体を使用して表される限り、これは完全にエレガントだと思います。
それがC標準で保証されているかどうかは覚えていませんが、ほとんどのCPUで事実上保証されています(私の経験では)。編集: これを適切に は C標準で保証されています。
名前の定数が必要な場合は、使用しないでください const
別の回答で提案されている資格のある変数。彼らは本当に同じではありません。マクロ(他の人が言ったように)または列挙タイプ定数のいずれかを使用します。
enum { GLushort_SENTINEL = -1; };
標準は、これが常にであることを保証します int
(本当に定数の別の名前 -1
)そして、それは常に署名されていないタイプの最大値に変換されること。
編集: またはあなたはそれを持つことができます
enum { GLushort_SENTINEL = (GLushort)-1; };
いくつかのアーキテクチャでそれを恐れるなら GLushort
より狭くなる可能性があります unsigned int
.