2011-06-15 63 views
3

我传递顶点索引的阵列中的一些GL代码的阵列使用-1为定点......每个元素都是一个GLushortC/GL:对无符号整数

我想用一个定点,以终止以避免每次与阵列本身一起辛苦地传递阵列长度。

#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

你们太棒了!谢谢! – 2011-06-16 00:08:28

回答

5

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

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

这是否可用作代码中的定点值取决于(GLushort)-1是否是代码中的有效非定点值。

+3

最后,知道'(无符号类型)-1'的人有效。 – 2011-06-15 13:00:37

1

我会创造一个有价值的全局常量:

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

我觉得这是非常优雅只要有符号整数用2的补码表示即可。我不记得C标准是否保证了这一点,但是它对于大多数CPU(根据我的经验)实际上是有保证的。 编辑: Appparently此 C标准保证....

+2

即使机器不使用补码表示,它也由C标准保证。 – 2011-06-15 12:52:37

+1

@SCM:我想你错过了那里的类型:'const GLushort GLushort_SENTINEL =(GLushort)( - 1);' – 2011-06-15 23:42:13

+0

绝对正确,我没有看到它,谢谢 – 2011-07-26 20:45:07

1

GLushort是被typedef操作到unsigned short一个UNSIGNED_SHORT类型,其虽然Ç不保证它,OpenGL的假设作为值为2^16-1范围(规范的第4.3章)。在几乎所有的主流架构上,这个有点危险的假设也是如此(我不知道其中一个在哪里unsigned short有不同的大小)。

因此,您可以使用 -1,却是尴尬的,因为你将有很多铸件,如果你在if()声明忘记例如转换,你可以幸运,并得到一个编译器警告“比较永远不会是真的”,或者你可能是不幸,编译器会默默优化分支,然后花几天时间寻找你的看似完美的代码执行错误的原因。或者更糟糕的是,它在调试版本中都能正常工作,而且在发布版本中只有炸弹。

因此,使用0xffff如jv42所建议的是更可取的,它可以避免所有这些陷阱。

+2

“short”不是2字节的架构似乎分为三大类:旧式超级计算机,古老的计算机和DSP。 – 2011-06-15 13:03:33

0

如果你想要一个命名常量,你不应该使用const合格变量在另一个答案建议。他们真的不一样。使用一个宏(如其他人所说的)或枚举类型常量:

enum { GLushort_SENTINEL = -1; }; 

标准的保证,这始终是一个int(真正的另外一个常量-1的名称),它总是会转化为最大你的无符号类型的值。

编辑:或者你可以把它

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

,如果你担心,在一些系统上GLushort可能比unsigned int窄。

+0

然而,如果你比较'(GLushort)x == GLushort_SENTINEL',你会调用“未定义的行为”,GCC至少总会产生'false'/0. – 2011-06-15 14:23:43

+0

@Dietrich,为什么这应该是未定义的行为? – 2011-06-15 18:14:13

+0

对不起,它通常不会调用未定义的行为(虽然它会在'short'和'int'具有相同范围的系统上)。我错过了整数促销的细微差别之一。但是,比较将**总是**在行为由标准定义的系统上返回“false”。 (比较'(无符号)x ==(int)y'总是未定义的,这正是我最初想到的。) – 2011-06-15 19:35:49