3

いくつかの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に相当する定数が見つかりません。そうでない場合は、それを使用します)

4

4 に答える 4

5

GLushortが実際に符号なしの型である場合、はの(GLushort)-1最大値ですGLushortC規格はそれを保証します。だから、あなたは安全に使うことができます-1

たとえば、C89には。SIZE_MAXの最大値のマクロがありませんでしたsize_t。これは、ユーザーが移植可能に定義できます#define SIZE_MAX ((size_t)-1)

これがコード内の番兵値として機能するかどうか(GLushort)-1は、コード内で有効な非番兵値であるかどうかによって異なります。

于 2011-06-15T12:51:48.557 に答える
1

値のグローバル定数を作成します。

const GLushort GLushort_SENTINEL = (GLushort)(-1);

符号付き整数が2の補数を使用して表されている限り、これは完全にエレガントだと思います。

それがC標準によって保証されているかどうかは覚えていませんが、ほとんどのCPUで事実上保証されています(私の経験では)。 編集:どうやらこれC標準によって保証されています...。

于 2011-06-15T11:21:09.030 に答える
1

GLushortはタイプ定義されたUNSIGNED_SHORTタイプでありunsigned short、Cはそれを保証しませんが、OpenGLは2 ^ 16-1の範囲の値として想定します(仕様の第4.3章)。事実上すべての主流のアーキテクチャでは、このやや危険な仮定も当てはまります(unsigned shortサイズが異なるものはわかりません)。

そのため、 -1を使用できif()ますが、キャストが多くなるため厄介です。たとえば、ステートメントでキャストを忘れた場合、幸運にも「比較は真になることはありません」というコンパイラの警告が表示される可能性があります。 、または不運な場合があり、コンパイラはブランチをサイレントに最適化します。その後、一見完璧に見えるコードが正しく実行されない理由を探すために何日も費やします。さらに悪いことに、デバッグビルドではすべて正常に機能し、リリースビルドでは爆弾のみが機能します。

したがって、0xffffjv42がアドバイスしているように使用することをお勧めします。これにより、この落とし穴を完全に回避できます。

于 2011-06-15T11:21:45.140 に答える
0

名前付き定数が必要な場合はconst、別の回答で提案されている修飾変数を使用しないでください。それらは実際には同じではありません。マクロ(他の人が言っているように)または列挙型定数のいずれかを使用します。

enum { GLushort_SENTINEL = -1; };

この標準は、これが常にint(実際には定数の別の名前-1)であり、常に符号なし型の最大値に変換されることを保証します。

編集:またはあなたはそれを持つことができます

enum { GLushort_SENTINEL = (GLushort)-1; };

GLushort一部のアーキテクチャでは、よりも狭くなる可能性があることを恐れている場合unsigned int

于 2011-06-15T13:47:41.807 に答える