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()语句中忘记了强制转换,您可能会很幸运并收到有关“比较永远不会为真”的编译器警告,或者你可能很不幸,编译器会默默地优化分支,之后你会花几天时间寻找看似完美的代码执行错误的原因。或者更糟糕的是,它在调试版本中一切正常,而在发布版本中只有炸弹。

因此,0xffff按照 jv42 的建议使用是更可取的,它完全避免了这个陷阱。

于 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 回答