C / GL:在无符号整数数组上使用-1作为哨兵

时间:2011-06-15 11:02:34

标签: c arrays opengl-es-2.0 unsigned-integer sentinel

我在一些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 个答案:

答案 0 :(得分:5)

如果GLushort确实是无符号类型,则(GLushort)-1GLushort的最大值。 The C standard guarantees that。因此,您可以安全地使用-1

例如,C89没有SIZE_MAX宏来表示size_t的最大值。它可以由用户轻松定义为#define SIZE_MAX ((size_t)-1)

这是否可以作为代码中的标记值取决于(GLushort)-1是否是代码中有效的非哨兵值。

答案 1 :(得分:1)

我会创建一个全局值的常量:

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

我认为只要使用2的补码表示有符号整数,这就非常优雅。

我不记得C标准是否保证了这一点,但对于大多数CPU来说几乎都有保证(根据我的经验)。 修改:显然,这个 由C标准保证....

答案 2 :(得分:1)

GLushort是一个UNSIGNED_SHORT类型,其类型定义为unsigned short,虽然C 不保证,但OpenGL假定为一个值为2 ^ 16-1范围(规范的第4.3章)。在几乎所有的主流架构中,这个有点危险的假设也是正确的(我不知道unsigned short有不同大小的那个。)

因此,你可以使用-1,但它很尴尬,因为你会有很多演员阵容,如果你在if()语句中忘记演员,你可以是幸运并得到编译器警告“比较永远不会是真的”,或者你可以运气不好并且编译器将默默地优化分支,之后你花费数天时间寻找你看似完美的代码执行错误的原因。或者更糟糕的是,它在调试版本中都运行良好,在发布版本中只有炸弹。

因此,使用0xffff作为jv42建议是非常优先的,它完全避免了这个陷阱。

答案 3 :(得分:0)

如果需要命名常量,则不应使用另一个答案中建议的const限定变量。他们真的不一样。使用宏(如其他人所说)或枚举类型常量:

enum { GLushort_SENTINEL = -1; };

标准保证这始终是int(常量-1的另一个名称)并且它总是会转换为无符号类型的最大值。

编辑:或者你可以拥有它

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

如果您担心某些架构GLushort可能比unsigned int更窄。