我在一些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等效常量,否则我将使用它)
答案 0 :(得分:5)
如果GLushort
确实是无符号类型,则(GLushort)-1
是GLushort
的最大值。 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
更窄。